Django rest framework изменить первичный ключ, чтобы использовать поле unqiue
У меня есть модель, которая называется GameProfile
, которая является отношением "один к одному" с моделью User
. Я использовал HyperlinkedModelSerializer
во всем моем дизайне.
Для GameProfile
поле пользователя должно быть основным ключом для запроса, оно уникально, но я не настроил его как первичный ключ. Есть ли способ изменить поведение по умолчанию для django serializer, чтобы указать на user__id
в качестве первичного ключа и всегда использовать его для получения профиля в подробном представлении?
class GameProfileSerializer(serializers.HyperlinkedModelSerializer):
"""
"""
user_pk = serializers.Field(source='user.id')
class Meta:
model = GameProfile
class GameProfileViewSet(viewsets.ModelViewSet):
"""
"""
queryset = GameProfile.objects.all()
serializer_class = GameProfileSerializer
def get_queryset(self):
""" get_queryset
"""
queryset = super(GameProfileViewSet, self).get_queryset()
if not queryset.exists():
raise Http404
if self.request.user.is_authenticated() and not self.request.user.is_superuser:
return queryset.filter(user=self.request.user)
return queryset
пожалуйста, сообщите, спасибо заранее:)
Ответы
Ответ 1
Предполагая, что ваша модель GameProfile
выглядит следующим образом:
class GameProfile(models.Model)
user = models.OneToOneField('User')
Сериализатор будет:
class GameProfileSerializer(serializers.HyperlinkedModelSerializer):
user_id = serializers.Field(source='user.id')
class Meta:
model = GameProfile
Установите атрибут .lookup_field
в представлении правильно:
lookup_field = 'user_id'
Url будет:
/gameprofile/<user_id>
Ответ 2
Чтобы заставить URL-адреса работать, вам может потребоваться добавить lookup_field
в ViewSet, а не только в сериализатор. Таким образом, у вас будет:
class GameProfileViewSet(viewsets.ModelViewSet):
queryset = GameProfile.objects.all()
serializer_class = GameProfileSerializer
lookup_field = 'user__id'
В этом случае lookup_field
использует ноту с двойным подчеркиванием, а не точечную нотацию (точки не будут работать в регулярных выражениях в шаблонах URL). Мне не удалось найти решение, предложенное @almalki и @patsweet для работы; в соответствии с документацией для сериализаторов: "Значение этой опции [ lookup_field
] должно соответствовать как kwarg в URL conf, так и с полем на модели", поэтому возможно, что он не работает с RelatedFields.
Ответ 3
Если я правильно понимаю ваш вопрос, вам нужна структура URL-адреса:
/api/<GameProfile-resource>/<user-pk>
Если это так, вы должны проверить вариант lookup_field
. Ссылка
Класс Serializer будет выглядеть примерно так:
class GameProfileSerializer(serializers.HyperlinkedModelSerializer):
"""
"""
user_pk = serializers.Field(source='user.id')
class Meta:
model = GameProfile
lookup_field = 'user_pk' # Might have to use 'user__id'