Python 在Django序列化程序中,如何基于视图参数设置外键字段?
使用Django REST框架,我希望允许用户通过Python 在Django序列化程序中,如何基于视图参数设置外键字段?,python,django,serialization,django-rest-framework,Python,Django,Serialization,Django Rest Framework,使用Django REST框架,我希望允许用户通过ListCreateAPIView(通过POST)创建和保存Django模型的实例。其中一个字段(外键字段称为domain)应根据url.py中定义的视图参数确定 此外,用户可以在以后使用PUT或PATCH请求对RetrieveUpdateDestroyAPIView端点修改模型实例(使用相同的序列化程序)。我不希望用户此时能够修改域字段 虽然我已经准备好了模型和视图/序列化程序结构的代码,但我不知道如何告诉序列化程序根据view参数确定域字段的
ListCreateAPIView
(通过POST
)创建和保存Django模型的实例。其中一个字段(外键字段称为domain
)应根据url.py
中定义的视图参数确定
此外,用户可以在以后使用PUT
或PATCH
请求对RetrieveUpdateDestroyAPIView
端点修改模型实例(使用相同的序列化程序)。我不希望用户此时能够修改域
字段
虽然我已经准备好了模型和视图/序列化程序结构的代码,但我不知道如何告诉序列化程序根据view参数确定域
字段的值。以下是我得到的:
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)
。。。和一个直接的列表CreateApiView
:
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)
url.py
包含以下行:
url(r'^domains/(?P<name>[a-zA-Z\.\-_0-9]+)/rrsets/$', RRsetsDetail.as_view(), name='rrsets')
问题:
name
参数中获取domain
名称只读字段
设置可防止用户稍后修改域
字段。但是,我不确定此设置是否与尝试设置默认值的序列化程序交互(即使设置了只读,序列化程序是否可以写入默认值)总而言之:我要找的是一个类似“基于视图参数的具有默认值的write once字段”。我想您要找的是一个具有 HiddenField 一个字段类,它不基于用户输入获取值,而是从默认值或可调用值获取值 CreateOnlyDefault 一个默认类,在运行期间只能用于设置默认参数 创建操作。在更新过程中,该字段被忽略 它只接受一个参数,即默认值或可调用参数 在创建操作期间应使用的 因为您想要访问视图,所以不能只使用callable,而是必须使用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()))
谢谢,这看起来很有希望。但是,我得到了以下错误(| |由我,表示换行):回溯(最近一次调用最后一次):[…]文件/usr/local/lib/python3.5/site packages/rest_framework/fields.py”,第257行,在set|context | self.default.set_context(serializer|field)| TypeError:set_context()缺少1个必需的位置参数:“serializer_field”我无法找出问题所在。您知道吗?实例化
DomainDefault
类,即使用DomainDefault()
而不仅仅是DomainDefault
。我会更新答案的。
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()))