gpt4 book ai didi

python - 在 Django 序列化程序中,如何根据 View 参数设置外键字段?

转载 作者:太空宇宙 更新时间:2023-11-03 12:02:40 24 4
gpt4 key购买 nike

使用 Django REST 框架,我希望允许用户通过 ListCreateAPIView(通过 POST)创建和保存 Django 模型的实例。其中一个字段(称为 domain 的外键字段)应根据 urls.py 中定义的 View 参数确定。

此外,用户可以稍后使用 PUTPATCH 请求到 RetrieveUpdateDestroyAPIView 端点(使用相同的序列化程序)修改模型实例。我不希望用户此时能够修改 domain 字段。

虽然我已准备好模型代码和 View /序列化程序结构,但我不确定如何告诉序列化程序根据 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',)

问题:

  1. 我需要修改什么才能让序列化程序从 View name 参数中获取 domain 名称?
  2. 序列化程序的 read_only_fields 设置可防止用户稍后修改 domain 字段。但是,我不确定此设置是否以某种方式与尝试设置默认值的序列化程序交互(序列化程序是否可以写入默认值,即使设置了只读)?

总结一下:我正在寻找的是类似于“具有基于 View 参数的默认值的一次写入字段”。

最佳答案

我认为您正在寻找 HiddenFieldCreateOnlyDefault 的组合

HiddenField

A field class that does not take a value based on user input, but instead takes its value from a default value or callable.

CreateOnlyDefault

A default class that can be used to only set a default argument during create operations. During updates the field is omitted.

It takes a single argument, which is the default value or callable that should be used during create operations.

而且因为要访问 View ,不能只用callable,还得用Class-based可以访问上下文数据的可调用对象。

class DomainDefault(object):
def set_context(self, serializer_field):
view = serializer_field.context['view']
request = serializer_field.context['request']
self.domain = ...#determine the domain based on request+view

def __call__(self):
return self.domain


class RRsetSerializer(serializers.ModelSerializer):
domain = serializers.HiddenField(default=serializers.CreateOnlyDefault(DomainDefault()))

关于python - 在 Django 序列化程序中,如何根据 View 参数设置外键字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43853005/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com