加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

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

发布时间:2020-12-20 13:17:36 所属栏目:Python 来源:网络整理
导读:使用Django REST Framework,我想允许用户通过ListCreateAPIView(通过POST)创建和保存Django模型的实例.其中一个字段(称为域的外键字段)应根据urls.py中定义的视图参数确定. 此外,用户可以稍后使用对RetrieveUpdateDestroyAPIView端点的PUT或PATCH请求(使用相
使用Django REST Framework,我想允许用户通过ListCreateAPIView(通过POST)创建和保存Django模型的实例.其中一个字段(称为域的外键字段)应根据urls.py中定义的视图参数确定.

此外,用户可以稍后使用对RetrieveUpdateDestroyAPIView端点的PUT或PATCH请求(使用相同的序列化程序)修改模型实例.我不希望用户此时能够修改域字段.

虽然我已准备好模型的代码和视图/序列化器结构,但我不知道如何告诉序列化程序根据视图参数确定域字段的值.这是我得到的:

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对象(名称字段仅为完整性而列出,但我不认为它在此上下文中很重要):

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',)

问题:

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

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

解决方法

我认为你正在寻找 HiddenField与 CreateOnlyDefault的组合

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.

而且因为你想访问视图,你不能只使用callable,但你必须使用Class-based callable,它可以访问上下文数据.

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()))

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读