此QueryDict实例是不可变的 [英] This QueryDict instance is immutable

查看:144
本文介绍了此QueryDict实例是不可变的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个分支模型,该模型具有帐户的外键(分支的所有者):

I have a Branch model with a foreign key to account (the owner of the branch):

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

    ...

我有一个带有用户外键的帐户模型(一对一字段):

I have a Account model with a foreign key to user (one to one field):

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,它显示了登录用户所拥有的分支:

I've created a ModelViewSet for Branch which shows the branch owned by the logged in user:

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保存帐户字段,不包含其余客户端发送的数据(以提高安全性)。例如:

Now to create a new branch, I want to save account field with request.user.account, not with data sent from the rest client (for more security). for example:

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,不能更改)。

but I got this error: This QueryDict instance is immutable. (means request.data is a immutable QueryDict and can't be changed)

您知道在使用Django rest框架创建对象时添加其他字段的更好方法吗?

Do you know any better way to add additional fields when creating an object with django rest framework?

推荐答案

如您在 Django文档


正常请求/响应周期中访问时, request.POST request.GET 中的QueryDicts 是不可变的。

The QueryDicts at request.POST and request.GET will be immutable when accessed in a normal request/response cycle.

,因此您可以使用同一文档中的建议:

so you can use the recommendation from the same documentation:


要获取可变版本,您需要使用 QueryDict.copy()

或。例如,如果出于某种原因需要保留对对象的引用或使对象保持不变,请使用一个小技巧。

or ... use a little trick, for example, if you need to keep a reference to an object for some reason or leave the object the same:

# remember old state
_mutable = data._mutable

# set to mutable
data._mutable = True

# сhange the values you want
data['param_name'] = 'new value'

# set mutable flag back
data._mutable = _mutable

其中数据是您的 QueryDicts

这篇关于此QueryDict实例是不可变的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆