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

查看:32
本文介绍了这个 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.POSTrequest.GET 中的 QueryDicts正常请求/响应周期中访问时将是不可变的.

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

so you can use the recommendation from the same documentation:

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

To get a mutable version you need to use 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天全站免登陆