使用Django REST Framework,我想允许用户通过 ListCreateAPIView
(通过 POST
)创建和保存Django模型的实例 . 其中一个字段(称为 domain
的外键字段)应根据 urls.py
中定义的视图参数确定 .
此外,用户可以稍后使用 PUT
或 PATCH
请求修改模型实例到 RetrieveUpdateDestroyAPIView
endpoints (使用相同的序列化程序) . 我不希望用户此时能够修改 domain
字段 .
虽然我已准备好模型的代码和视图/序列化器结构,但我不知道如何告诉序列化程序根据view参数确定 domain
字段的值 . 这是我得到的:
class RRset(models.Model):
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(null=True)
domain = models.ForeignKey(Domain, on_delete=models.CASCADE, related_name='rrsets')
subname = models.CharField(max_length=255, blank=True)
type = models.CharField(max_length=10)
......和一个直截了当的 ListCreateAPIView
:
class RRsetsDetail(generics.ListCreateAPIView):
serializer_class = RRsetSerializer
permission_classes = (permissions.IsAuthenticated,)
def get_queryset(self):
name = self.kwargs['name']
return RRset.objects.filter(domain__name=name, domain__owner=self.request.user.pk)
urls.py
包含以下行:
url(r'^domains/(?P<name>[a-zA-Z\.\-_0-9]+)/rrsets/$', RRsetsDetail.as_view(), name='rrsets')
这允许用户使用 RRsetsSerializer
序列化程序列出和创建 RRset
对象(仅列出 name
字段是为了完整性,但我不认为它在此上下文中很重要):
class RRsetSerializer(serializers.ModelSerializer):
name = serializers.SerializerMethodField()
def get_name(self, obj):
return '.'.join(filter(None, [obj.subname, obj.domain.name])) + '.' # returns 'subname.name.'
class Meta:
model = RRset
fields = ('created', 'updated', 'domain', 'name', 'type',)
read_only_fields = ('created', 'updated', 'domain', 'type',)
问题:
-
我需要修改什么才能让序列化程序从视图
name
参数中获取domain
名称? -
序列化程序的
read_only_fields
设置可防止用户稍后修改domain
字段 . 但是,我不确定此设置是否以某种方式与序列化程序交互尝试设置默认值(即使设置了只读,串行器是否可以写入默认值)?
总结一下:我正在寻找的是“具有基于视图参数的默认值的一次写入字段” .
1 回答
我想你正在寻找HiddenField与CreateOnlyDefault的组合
而且因为你想访问视图,你不能只使用callable,但你必须使用Class-based callable,它可以访问上下文数据 .