Django序列化程序queryset和检索外键值

时间:2019-03-06 00:52:39

标签: python json django

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

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

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数据中吗?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

默认情况下,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'))