我的模型包含User
模型和Present
模型。 User
可以有多个Present
,但Present
有唯一的User
:
我的models.py
是:
from django.db import models
from django.contrib.auth.models import User
class Present(models.Model):
name = models.CharField(max_length=15)
price = models.FloatField()
link = models.CharField(max_length=15)
isAlreadyBought = models.BooleanField()
user = models.ForeignKey(User, related_name='presents', on_delete=models.CASCADE)
我的serializers.py
是:
from django.contrib.auth.models import User, Group
from rest_framework import serializers
from blog.models import Present, Location
from django.contrib.auth.models import User
class UserSerializer(serializers.ModelSerializer):
presents = serializers.PrimaryKeyRelatedField(many=True, queryset=Present.objects.all(), required=False)
class Meta:
model = User
fields = ('username', 'password', 'email', 'presents')
def create(self, validated_data):
user = super().create(validated_data)
if 'password' in validated_data:
user.set_password(validated_data['password'])
user.save()
return user
class PresentSerializer(serializers.ModelSerializer):
user = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(), read_only=False, many=False)
class Meta:
model = Present
fields = ('name', 'link', 'price', 'isAlreadyBought', 'user')
def create(self, validated_data):
return Present.objects.create(**validated_data)
目前,如果我想获得与给定用户关联的所有礼物,我使用主键(在views.py
中):
class PresentsOfUser(viewsets.ModelViewSet):
queryset = Present.objects.all().filter(user=33)
serializer_class = PresentSerializer
但是,我宁愿使用username
的{{1}}字段而不是主键。
我尝试使用User
,但我不确定这是实现目标的正确方法:
SlugRelatedField
通过此修改,我现在使用以下class PresentSerializer(serializers.ModelSerializer):
user = serializers.SlugRelatedField(queryset=User.objects.all(), slug_field='username', read_only=False, many=False)
class Meta:
model = Present
fields = ('name', 'link', 'price', 'isAlreadyBought', 'user')
def create(self, validated_data):
return Present.objects.create(**validated_data)
来获取View
为'Marcel'
的用户id
:
33
但在这种情况下,我得到:
class PresentsOfUser(viewsets.ModelViewSet):
queryset = Present.objects.all().filter(user='Marcel')
serializer_class = PresentSerializer
但如果我将ValueError: invalid literal for int() with base 10: 'Marcel'
替换为user='Marcel'
(如前所述),我会得到:
user=33
用户字段现在是[{"name":"Nintendo","link":"fake_link","price":50.8,"isAlreadyBought":true,"user":"Marcel"},{"name":"Gamecube","link":"fake_link","price":50.8,"isAlreadyBought":true,"user":"Marcel"}]
而不是用户的username
。
但是,我不明白为什么使用id
进行过滤会失败...
答案 0 :(得分:1)
我最终通过覆盖get_queryset
方法,同时将PrimaryKeyRelatedField
保留在我的序列化程序中(user__username='Marcel'
为mishbah建议):
class PresentsOfUser(viewsets.ModelViewSet):
serializer_class = PresentSerializer
def get_queryset(self):
"""
Optionally restricts the returned purchases to a given user,
by filtering against a `username` query parameter in the URL.
"""
queryset = Present.objects.all()
username = self.kwargs['user']
if username is not None:
queryset = queryset.filter(user__username=username)
if len(queryset) == 0:
raise Http404
return queryset
将PrimaryKeyRelatedField
替换为SlugRelatedField
时,它也有效:
user = serializers.SlugRelatedField(queryset=User.objects.all(), slug_field='username', read_only=False, many=False)
并在to_field='username'
模型的ForeignKey
中添加Present
:
user = models.ForeignKey(User, related_name='presents', to_field='username', on_delete=models.CASCADE)