我有一个带有外键帐户的分支模型(分支的所有者):
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'),)
...
我有一个带有用户外键的帐户模型(一对一字段):
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 framework创建对象时,您是否知道添加其他字段的更好方法?
答案 0 :(得分:6)
如您在Django documentation中所见:
在正常请求/响应周期中访问 request.POST 和 request.GET 的 QueryDicts 将是不可变的< / em>。
因此您可以使用同一文档中的建议:
要获取可变版本,您需要使用 QueryDict.copy()
或...使用一些小技巧,例如,如果出于某种原因需要保留对对象的引用或使该对象保持不变:
# 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
答案 1 :(得分:1)
在使用django rest framework创建对象时,您是否知道添加其他字段的更好方法?
在创建/更新对象时提供额外数据的官方方法是将其传递给$res = $this->find( 'all', $cond); // All the data are fetchd from this $res
$count = count($res);
for($i=0;$i<$count;$i++){
$result[] = $res[$i] ;
$fixed_arrays[] = $result[$i]['MyData'];
if (!empty($result[$i]['c'])) {
$corrupt_c_array = $result[$i]['c'];
$fixed_arrays = array_merge($fixed_arrays,$corrupt_c_array);
}
if(!empty($result[$i]['a'])) {
$corrupt_a_array = $result[$i]['a'];
$fixed_arrays = array_merge($fixed_arrays, $corrupt_a_array);
}
}
$result['data'] = $fixed_arrays; // This $result['data'] should show the expected result.
,如图所示here
答案 2 :(得分:0)
https://docs.djangoproject.com/en/2.0/ref/request-response/#querydict-objects
在request.POST和request.GET中的QueryDicts在正常的请求/响应周期中访问时将是不可变的。要获得可变版本,您需要使用QueryDict.copy()。
答案 3 :(得分:0)
我个人认为编写这样的代码会更优雅。
def create(self, request, *args, **kwargs):
data = OrderedDict()
data.update(request.data)
data['account'] = request.user.account
serializer = self.get_serializer(data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)