【发布时间】:2017-11-26 19:09:22
【问题描述】:
我有一个带有外键帐户的分支模型(分支的所有者):
class Branch(SafeDeleteModel):
_safedelete_policy = SOFT_DELETE_CASCADE
name = models.CharField(max_length=100)
account = models.ForeignKey(Account, null=True, on_delete=models.CASCADE)
location = models.TextField()
phone = models.CharField(max_length=20, blank=True,
null=True, default=None)
create_at = models.DateTimeField(auto_now_add=True, null=True)
update_at = models.DateTimeField(auto_now=True, null=True)
def __str__(self):
return self.name
class Meta:
unique_together = (('name','account'),)
...
我有一个带有用户外键的 Account 模型(一对一字段):
class Account(models.Model):
_safedelete_policy = SOFT_DELETE_CASCADE
name = models.CharField(max_length=100)
user = models.OneToOneField(User)
create_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name + ' - ' + self.create_at.strftime('%Y-%m-%d %H:%M:%S')
我为 Branch 创建了一个 ModelViewSet,它显示了登录用户拥有的分支:
class BranchViewSet(viewsets.ModelViewSet):
serializer_class = BranchSerializer
permission_classes = (permissions.IsAuthenticated,)
def get_queryset(self):
queryset = Branch.objects.all().filter(account=self.request.user.account)
return queryset
现在要创建一个新分支,我想用 request.user.account 保存帐户字段,而不是从其余客户端发送的数据(为了提高安全性)。例如:
def create(self, request, *args, **kwargs):
if request.user.user_type == User.ADMIN:
request.data['account'] = request.user.account
return super(BranchViewSet, self).create(request, *args, **kwargs)
def perform_create(self, serializer):
'''
Associate branch with account
'''
serializer.save(account=self.request.user.account)
在分支序列化器中
class BranchSerializer(serializers.ModelSerializer):
account = serializers.CharField(source='account.id', read_only=True)
class Meta:
model = Branch
fields = ('id', 'name', 'branch_alias',
'location', 'phone', 'account')
validators = [
UniqueTogetherValidator(
queryset=Branch.objects.all(),
fields=('name', 'account')
)
]
但我得到了这个错误: 此 QueryDict 实例是不可变的。 (意味着 request.data 是一个不可变的 QueryDict 并且不能更改)
您知道在使用 django rest 框架创建对象时添加额外字段的更好方法吗?
【问题讨论】:
-
覆盖
perform_create是这里要做的事情,并且完全按照您的意愿行事,所以我不知道您为什么需要更改create或根本修改 QueryDict。 -
你能举个例子吗?
-
我不需要展示示例,您已经有了正确的代码。只需摆脱
create方法,因为您在perform_create中编写的内容正是您想要的。 -
但是调用API时传递的数据呢?
-
我不明白你的意思。序列化程序已经有了 post 数据。
标签: django django-models django-rest-framework