Anu*_*TBE 9 django django-serializer django-rest-framework
我正在使用Django 2.x
和Django REST Framework
。
我有两个模型,比如
class Contact(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.ForeignKey(User, on_delete=models.PROTECT)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100, blank=True, null=True)
modified = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class AmountGiven(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
contact = models.ForeignKey(Contact, on_delete=models.PROTECT)
amount = models.FloatField(help_text='Amount given to the contact')
given_date = models.DateField(default=timezone.now)
created = models.DateTimeField(auto_now=True)
Run Code Online (Sandbox Code Playgroud)
该serializer.py文件已串行定义为
class ContactSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Contact
fields = ('id', 'first_name', 'last_name', 'created', 'modified')
class AmountGivenSerializer(serializers.ModelSerializer):
contact = ContactSerializer()
class Meta:
model = AmountGiven
depth = 1
fields = (
'id', 'contact', 'amount', 'given_date', 'created'
)
Run Code Online (Sandbox Code Playgroud)
视图.py
class AmountGivenViewSet(viewsets.ModelViewSet):
serializer_class = AmountGivenSerializer
def perform_create(self, serializer):
save_data = {}
contact_pk = self.request.data.get('contact', None)
if not contact_pk:
raise ValidationError({'contact': ['Contact is required']})
contact = Contact.objects.filter(
user=self.request.user,
pk=contact_pk
).first()
if not contact:
raise ValidationError({'contact': ['Contact does not exists']})
save_data['contact'] = contact
serializer.save(**save_data)
Run Code Online (Sandbox Code Playgroud)
但是当我向AmountGiven模型添加新记录并contact
在contact
字段中传递id 时
它给出了错误
{"contact":{"non_field_errors":["Invalid data. Expected a dictionary, but got str."]}}
Run Code Online (Sandbox Code Playgroud)
当我contact = ContactSerializer()
从AmountGivenSerializer 中删除时,它按预期工作正常,但作为响应depth
设置为 1,联系人数据仅包含模型字段,而不包含其他定义的属性字段。
我不是这种请求解析模式的忠实粉丝。据我了解,您希望能够在检索AmountGiven
对象时查看所有联系人的详细信息,同时AmountGiven
只需提供联系人 ID即可创建和更新。
因此,您可以将AmountGiven
序列化程序更改为contact
模型字段的2 个字段。像这样:
class AmountGivenSerializer(serializers.ModelSerializer):
contact_detail = ContactSerializer(source='contact', read_only=True)
class Meta:
model = AmountGiven
depth = 1
fields = (
'id', 'contact', 'contact_detail', 'amount', 'given_date', 'created'
)
Run Code Online (Sandbox Code Playgroud)
请注意,该contact_detail
字段有一个source
属性。
现在创建和更新的默认功能应该是开箱即用的(验证和一切)。
当您检索一个AmountGiven
对象时,您应该获得该contact_detail
字段中联系人的所有详细信息。
我错过了您需要检查 是否Contact
属于用户(但是,我没有user
在您的Contact
模型上看到字段,也许您错过了发布它)。您可以简化该检查:
class AmountGivenViewSet(viewsets.ModelViewSet):
serializer_class = AmountGivenSerializer
def perform_create(self, serializer):
contact = serializer.validated_data.get('contact')
if contact.user != self.request.user:
raise ValidationError({'contact': ['Not a valid contact']})
serializer.save()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
14494 次 |
最近记录: |