吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2596|回复: 2
收起左侧

[求助] django-rest,自定义viewsets.ModelViewSet中的create方法遇到的问题

[复制链接]
thepoy 发表于 2019-11-27 17:49
本帖最后由 thepoy 于 2019-11-27 18:08 编辑

有两个model,一个是user,一个是address,二者是一对多的关系,address中有外键指向user:

models:
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:
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方法如下:

    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': [1]}>
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呢?

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

pangdong697 发表于 2019-11-27 18:28
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']

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
thepoy + 1 + 1 谢谢@Thanks!

查看全部评分

 楼主| thepoy 发表于 2019-11-28 09:12
pangdong697 发表于 2019-11-27 18:28
class AddressSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = A ...

昨晚已经发现了,不过你说的跟我理解的不太一样,我个人觉得,user_id在数据库中是存在的,但在serializer.data中,user_id因为是外键引入的问题,默认是ReadOnlyField,解决这个ReadOnly需要重新在serializer中定义这个字段,解决办法正是与你的回答相同。
以上是我个人的理解,不知道对不对,但是是顺着这个思路解决的。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 21:43

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表