【问题标题】:Django serializer queryset and retrieve foreign key valuesDjango 序列化器查询集和检索外键值
【发布时间】:2019-03-06 00:52:39
【问题描述】:

我想获取与 TWEET 模型中的用户字段相关的用户名值。

这是我正在使用的两个模型:

class Tweet(models.Model):
    id = models.AutoField(db_column='ID', primary_key=True)  # Field name made lowercase.
    user = models.ForeignKey('USER', models.DO_NOTHING, db_column='USER_ID')  # Field name made lowercase.
    content = models.CharField(db_column='CONTENT', max_length=45)  # Field name made lowercase.
    timestamp = models.DateTimeField(db_column='TIMESTAMP')  # Field name made lowercase.
    like_counter = models.IntegerField(db_column='LIKE_COUNTER')  # Field name made lowercase.
    parent_tweet = models.ForeignKey('self', models.DO_NOTHING, db_column='PARENT_TWEET', blank=True, null=True)  # Field name made lowercase.True

class User(models.Model):
    id = models.AutoField(db_column='ID', primary_key=True)  # Field name made lowercase.
    username = models.CharField(db_column='USERNAME', max_length=45)  # Field name made lowercase.
    email = models.CharField(db_column='EMAIL', max_length=100)  # Field name made lowercase.
    password = models.CharField(db_column='PASSWORD', max_length=45)  # Field name made lowercase.

序列化查询集的函数:

#returns a queryset of first 5 tweets in order of most recent
tweet_data = Tweet.objects.filter(user_id__in = following_ids).filter().order_by('-timestamp')[:5]
tweet_data_json = serializers.serialize('json', tweet_data, fields=('id','user__username','content','timestamp','like_counter','parent_tweet'))
return tweet_data_json

在 serialize() 中,我使用 user__username 希望返回由 tweets 表中的用户值引用的用户名,但这不会出现在我的 json 数据中?

【问题讨论】:

  • 你说的是序列化器和视图集吗?

标签: python json django


【解决方案1】:

您可以在此过程中使用 Django Natural Keys 序列化。您需要将 User 模型更新为:

class User(models.Model):
    id = models.AutoField(db_column='ID', primary_key=True)  # Field name made lowercase.
    username = models.CharField(db_column='USERNAME', max_length=45)  # Field name made lowercase.
    email = models.CharField(db_column='EMAIL', max_length=100)  # Field name made lowercase.
    password = models.CharField(db_column='PASSWORD', max_length=45)  # Field name made lowercase.

    def natural_keys(self):
        return self.username

那么在调用serialize方法时,需要将use_natural_foreign_keys设置为True。示例:

tweet_data_json = serializers.serialize('json', tweet_data, use_natural_foreign_keys=True, use_natural_primary_key=True)

参考可以查看django-natural-keys

【讨论】:

    【解决方案2】:

    默认情况下,Django 在序列化器中不提供这样的值。但是您可以尝试覆盖它以获取所需的数据。例如,您可以像这样覆盖json serializer

    from django.core.serializers.json import Serializer
    
    class CustomSerializer(Serializer):
    
        def end_object(self, obj):
            for field in self.selected_fields:
                if field == 'pk':
                    continue
                elif field in self._current.keys():
                    continue
                else:
                    try:
                        if '__' in field:
                            fields = field.split('__')
                            value = obj
                            for f in fields:
                                value = getattr(value, f)
                            if value != obj:
                                self._current[field] = value
                        else:
                            self._current[field] = getattr(obj,field)
    
                    except AttributeError:
                        pass
            super(CustomSerializer, self).end_object(obj)
    

    现在您可以按如下方式使用此序列化程序:

    serializers = CustomSerializer()
    tweet_data_json = serializers.serialize(tweet_data, fields=('id','user__username','content','timestamp','like_counter','parent_tweet'))
    

    【讨论】:

      猜你喜欢
      • 2015-01-02
      • 2013-06-21
      • 2015-03-09
      • 2015-01-25
      • 2013-11-02
      • 1970-01-01
      • 2020-08-26
      • 2012-02-20
      • 2020-06-22
      相关资源
      最近更新 更多