写在前面
在使用Django-rest-framework提交并创建数据时,有时候服务器端需要对传过的来的数据进行处理并重新赋值后再创建到数据库。
例:
在我的models.py里面有两个表级联
# models.py
class User(models.Model):
u_name = models.CharField(max_length=32, unique=True)
class Addr(models.Model):
a_user = models.ForeignKey(User, on_delete=models.CASCADE)
a_order_id = models.IntegerField(default=0)
这时我要给用户添加一个新的地址。但是a_user字段不能让用户填写,而是后台通过查询User表后传过去,然后创建新的地址
# Serializer.py
class AddrSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Addr
fields = ('a_order_id', 'a_user')
1、思路
当我们不需要改变修改PORT提交的数据时
class AddrAPIView(ListCreateAPIView):
serializer_class = AddrSerializer
queryset = Addr.objects.all()
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
当我们需要改变修改PORT提交的数据时
# views.py
class AddrAPIView(ListCreateAPIView):
serializer_class = AddrSerializer
queryset = Addr.objects.all()
def post(self, request, *args, **kwargs):
data = QueryDict(request.data.urlencode(), mutable=True)
data.update({'a_user': 'http://127.0.0.1:8000/static/user/1/'})
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
return Response(serializer.data)
思路:
-
post方法里写入数据的是return self.create(request, *args, **kwargs)
-
我们通过查看create()源码发现,传递request数据的是:
serializer = self.get_serializer(data=request.data),
而这个request.data是QueryDict类型的(不能直接修改数据) -
request.data.urlencode()打印出来的是QueryDict()类型可以接收的源数据
-
‘a_user’ 字段在序列化serializer里面写了,网页里面可以不提交这个数据。但是在serializer里面不写这个字段,创建时会导致报错
2、更简单点
上面是利用Django-rest-framework里面的序列化工具创建的,其实这样改来改去反倒变得复杂了,当然如果前端需要这样的API返回还是很有必要的,其实可以直接创建addr = Addr(),然后手动戳你需要修改的数据,保存就可以了
class AddrAPIView(ListCreateAPIView):
serializer_class = AddrSerializer
queryset = Addr.objects.all()
def post(self, request, *args, **kwargs):
addr = Addr()
addr.a_user = User.objects.get(pk=u_id)
addr.a_order_id = request.data["a_order_id"]
addr.save()
return Response({"status": 901})