django-rest,自定义viewsets.ModelViewSet中的create方法遇到的问题
本帖最后由 thepoy 于 2019-11-27 18:08 编辑有两个model,一个是user,一个是address,二者是一对多的关系,address中有外键指向user:
#### models:
```python
class UserModel(models.Model):
name = models.CharField(max_length=20, unique=True)
password = models.CharField(max_length=256)
class Address(models.Model):
addr = models.CharField(max_length=128)
user = models.ForeignKey(UserModel, on_delete=models.CASCADE, null=True)
```
#### serializers:
```python
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = UserModel
fields = ['url', 'id', 'name', 'password']
class AddressSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Address
fields = ['url', 'id', 'addr', 'user_id']
```
希望在创建地址时,不需要在form中添加user_id,直接把地址中的user增加为现在登录的用户,所以修改create方法如下:
```python
def create(self, request, *args, **kwargs):
data = request.data.copy()
# 直接在把已登录的user_id添加到data中
# 试过把user_id改为user,结果一样
data.__setitem__('user_id', request.user.id)
print(data)
# 把已经添加过user_id的data作为序列化的参数
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
print(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
```
最后上面打印的结果:
```
data--><QueryDict: {'addr': ['重庆'], 'user_id': }>
serializer.data-->{'url': 'http://localhost:8000/app/address/16/', 'id': 16, 'addr': '重庆', 'user_id': None}
```
可以看见,data中user_id确实已经添加进去了,但是序列化后,serializer.data中的user_id却是None。
实在是搞不懂其中原理。
在为了减少IO、不修改Address的model的前提下,
如何才能在create中将address的user改为正在登录的user呢? class AddressSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Address
fields = ['url', 'id', 'addr', 'user_id']
其中的user_id 只是关键生成的,并不是在数据库中真实存在的,如果要使用需要在序列化中定义一下
class AddressSerializer(serializers.HyperlinkedModelSerializer):
user_id = serializers.IntegerField()
class Meta:
model = Address
fields = ['url', 'id', 'addr', 'user_id']
pangdong697 发表于 2019-11-27 18:28
class AddressSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = A ...
昨晚已经发现了,不过你说的跟我理解的不太一样,我个人觉得,user_id在数据库中是存在的,但在serializer.data中,user_id因为是外键引入的问题,默认是ReadOnlyField,解决这个ReadOnly需要重新在serializer中定义这个字段,解决办法正是与你的回答相同。
以上是我个人的理解,不知道对不对,但是是顺着这个思路解决的。
页:
[1]