Django 将带有外键的查询集转换为 JSON
Posted
技术标签:
【中文标题】Django 将带有外键的查询集转换为 JSON【英文标题】:Django Converting Queryset with Foreign Keys to JSON 【发布时间】:2019-07-14 10:34:36 【问题描述】:我正在尝试将 JSON 对象传递给我的模板。我有一些无法修改的复杂关系。基于操作系统 帖子我尝试了不同的东西。我认为让我亲近的是:
我创建了一个看起来像这样的 .values() 查询集
def my_queryset():
results=TodaysResults.objects.values('id','foreignModel1__name',
'foreignModel1__ForeignModel2__title')
print (myquery_set)
my_queryset 为我提供了我需要的所有值。所以我尝试使用以下方法对其进行转换。 1)
def make_querydict():
results=TodaysResults.objects.values('id','foreignModel1__name',
'foreignModel1__ForeignModel2__title')
json_results=json.dumps(list(results,cls=DjangoJSONEncoder))
print (json_results)
我收到以下错误:
"TypeError: list() 没有关键字参数"
2) 我也试过这个:
def serialize():
fields = ['id','foreignModel1__name','foreignModel1__ForeignModel2__title']
qs = TodaysResults.objects.all()
json_data = serializers.serialize('json',qs,fields=fields)
print(json_data)
但是当我打印 json_data 时,只显示 id 而不是外部值。
3)基于一些相同的答案like this(从2012年开始)我试过了:
def for_JSON_response():
response=JsonResponse(dict(results_info=list(TodaysResultslts.objects.values('id','foreignModel1__name',
'foreignModel1__ForeignModel2__title')
print(response)
我没有收到任何错误,但它没有打印任何内容。所以,我假设什么都没发生。
4) 基于this 我试过了:
def my_queryset():
results=TodaysResults.objects.values('id','foreignModel1__name',
'foreignModel1__ForeignModel2__title')
print (JsonResponse(results, safe=False))
我明白了:
TypeError:QuerySet 类型的对象不是 JSON 可序列化的
我试过了:
def my_queryset():
results=TodaysResults.objects.values('id','foreignModel1__name',
'foreignModel1__ForeignModel2__title')
results_json = serializers.serialize('json',results)
我得到了:
AttributeError: 'dict' 对象没有属性 '_meta'
我一直在四处寻找,有些回复看起来已经过时了。我上面的尝试是我认为最接近转换 valuesqueryset 到 json 或将我需要的值放入 JSON。有没有办法像我在 my_queryset 中那样进行链式查询并将其转换为 JSON?
模型.Py 为这个例子简化了
class TodaysResults(models.Model):
place = models.CharField(max_length=255)
ForeignModel1 = models.ForeignKey(ForeignModel,related_name='m1')
class ForeignModel(models.Model):
name = Models.CharField(max_length=255)
ForeignModel2 = models.ManyToManyField(M2M, related_name='m2')
class M2M(models.Model):
title = Models.CharField(max_length=255)
【问题讨论】:
你使用django-restframework
的序列化器link
我从未使用过 django-restframework。并不是我不接受它。只是 .values() my_queryset 已经拥有我需要的所有字段,我什至可以使用注释 F 将“foreignModel1__ForeignModel2__title”重命名为标题。DjangoRestFramework 可以用于序列化查询集吗?
是的,可以。您可以安全地使用它。它将帮助您以最低的负担做很多事情。
好的。我正在阅读您提供的链接,我看到了一些名为“serpy”的东西?我想我正在尝试找到可以使用查询集的东西?我关心的是外键和多对多字段。
我想建议阅读有关 ModelSerializer
的信息,我将发布一个答案,django-rest-framework 序列化程序如何解决您的问题。
【参考方案1】:
这里我们有三个模型TodaysResults
、ForeignModel
和MModel
,我猜MModel
是manyTomany
与ForeignModel
的关系。我提出了两种可能的方式,我们如何从TodaysResults
序列化程序中获取所有信息。
可能的解决方案一
from rest_framework import serializers
class MModelSerializer(serializers.ModelSerializer):
class Meta:
model = MModel
fields = ('title',)
class ForeignModelSerializer(serializers.ModelSerializer):
foreignModel2 = MModelSerializer(many=True) # as it is many to many field
class Meta:
model = ForeignModel
fields = ('name', 'foreignModel2',)
class TodaysResultsSerializer(serializers.ModelSerializer):
foreignModel1 = ForeignModelSerializer()
class Meta:
model = TodaysResults
fields = ('place', 'foreignModel1')
现在传递您的 TodaysResults
查询集 TodaysResultsSerializer 并从 serializer.data 获取您的序列化数据。
可能的解决方案二
即使我们可以用一个序列化来做到这一点,因为并非所有字段都是必需的。
class TodaysResultsSerializer(serializers.ModelSerializer):
class Meta:
model = TodaysResults
fields = ('place', 'foreignModel1__name', 'foreignModel1__foreignModel2__title')
虽然我不完全确定,但这也应该有效。
【讨论】:
您需要通过TodaysResults.objects.all()
的queryest 以获得第一个解决方案,在那里您将获得您想要的字段。第二个你的结果应该有效。以上是关于Django 将带有外键的查询集转换为 JSON的主要内容,如果未能解决你的问题,请参考以下文章