【问题标题】:django queryset annotate all field in childtabledjango queryset 注释子表中的所有字段
【发布时间】:2018-05-18 12:22:50
【问题描述】:

models.py

class Userinfo(models.Model):

    useruid = models.BigAutoField(db_column='UserUID', primary_key=True)

    useremail = models.CharField(
    db_column='UserEmail', unique=True, max_length=100)

    userpassword = models.CharField(db_column='UserPassword', max_length=128)

    passwordsalt = models.CharField(db_column='PasswordSalt', max_length=128)

    class Meta:
    managed = False
    db_table = 'userinfo'

class Postinfo(models.Model):


    postuid = models.BigAutoField(db_column='PostUID',primary_key=True)

    useruid = models.ForeignKey(
    'Userinfo', db_column='UserUID', on_delete=models.CASCADE)


    content = models.TextField(db_column='Content')

    class Meta:
          managed = False
          db_table = 'postinfo'

如果我得到用户列表和用户的最后一篇文章

我认为使用注释

models.Userinfo.objects.all().annotate(lastpost="??").order_by("-useruid")

“??”中有什么值

喜欢这个表格

[{userinfo1,"lastpost":{postinfofields}},{userinfo2,"lastpost":{postinfofields}},{userinfo3,"lastpost":{postinfofields}}]

这个查询可以不使用forloop吗?

序列化器.py

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Postinfo
        fields = ('postuid','content') 

class UserSerializer(serializers.ModelSerializer):   

     lastpost = PostSerializer() 

     class Meta:
        model = Userinfo
        fields = ['useruid', 'useremail', 'lastpost']

view.py

  userinfos = models.Userinfo.objects.all().order_by("-useruid")
  result = UserSerializer(userinfos,many=True)
  print(result.data)

引发异常

Got AttributeError when attempting to get a value for field `lastpost` on serializer `UserSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Userinfo` instance.
Original exception text was: 'Userinfo' object has no attribute 'lastpost'.

如果我添加 read_only=True 打印这个

[OrderedDict([('useuid', 1), ('useremail', 'test')]), OrderedDict([('useruid', 2), ('useremail', 'test2')])]

【问题讨论】:

    标签: django django-models django-rest-framework django-queryset


    【解决方案1】:

    您可以为此使用模型的属性:

    class Userinfo(models.Model):
    
        useruid = models.BigAutoField(db_column='UserUID', primary_key=True)
    
        useremail = models.CharField(
        db_column='UserEmail', unique=True, max_length=100)
    
        userpassword = models.CharField(db_column='UserPassword', max_length=128)
    
        passwordsalt = models.CharField(db_column='PasswordSalt', max_length=128)
    
        @property
        def lastpost(self):
            return self.postinfo_set.latest('postuid')
    

    现在您不需要注释,只需在模板中使用它即可:

    {{ user.lastpost.content }}
    

    UPD

    要使用ModelSerializer 序列化属性,只需添加序列化器的字段'lastpost'

    class PostSerializer(serializers.ModelSerializer):
        class Meta:
            model = Postinfo
            fields = ('postuid','content') 
    
    class UserSerializer(serializers.ModelSerializer):   
        lastpost = PostSerializer() 
    
        class Meta:
            model = Userinfo
            fields = ['useruid', 'useremail', 'lastpost']
    

    UPD2

    您也可以直接在序列化程序级别实现逻辑,无需模型的属性。只需使用SerializerMethodField

    class UserSerializer(serializers.ModelSerializer):   
        lastpost = SerializerMethodField() 
    
        class Meta:
            model = Userinfo
            fields = ['useruid', 'useremail', 'lastpost']
    
        def get_lastpos(self, obj):
            last = obj.postinfo_set.latest('postuid')
            serializer = PostSerializer(last)
            return serializer.data
    

    【讨论】:

    • 我必须返回 dict ,我可以制作 dict 吗?
    • @Adam 尝试使用序列化器。
    • 对不起,我不明白我是菜鸟...class serializer(serializers.ModelSerializer): class Meta: model = models.Userinfo fields = '__all__' @property def lastpost(self): return json.loads(serializers.serialize("json", self.postinfo_set.order_by('-postuid')[:1]))[0]这是对的吗?
    • 是的,我用过 drf 我真的很感激你所做的。祝你好运
    • @Adam 我添加了带有 DRF 序列化程序的示例。
    猜你喜欢
    • 2017-08-29
    • 2011-11-10
    • 2019-08-03
    • 2018-02-22
    • 1970-01-01
    • 2016-01-07
    • 2011-04-18
    • 1970-01-01
    • 2018-12-30
    相关资源
    最近更新 更多