Django的。如何从查询中排除一对多或多对多字段?

时间:2017-07-07 08:39:17

标签: python django many-to-many one-to-many

我有一个这样的样本模型:

class FooBar(models.Model):
    name = models.CharField ...
    age = models.IntegerField ...
    cats = models.ManyToManyField ...
    dogs = models.ManyToManyField ...

正如你所看到的,有2个多对多的领域(猫,狗)

然后(我的代码中的其他地方)我有序列化函数将给定的模型转换为JSON。例如

make_json(foobar_instance) will produce smth like this:

{
    "id": "9999",
    "name": "John Romero",
    "age": "55",
    "cats": "[421, 5423, 53252]",
    "dogs": "[213, 44124, 321, 753]"
}

但我不需要那些"猫"和#34;狗"我的结果中的字段是JSON,我不想通过额外的查询来收取数据库,以解决这种多对多的关系。

所以,我怎么能告诉Django:男人,将结果中的猫狗排除在外 - 我不需要那个东西。

例如

FooBar.objects.filter(....).SKIP('cats', 'dogs')...

这可能吗?

谢谢!

3 个答案:

答案 0 :(得分:0)

据我所知,Django的ORM在您尝试访问相关对象之前不会发出sql查询来检索相关对象,除非您使用select_related()和/或{{1}专门询问它们},所以最简单的解决方案是检查prefetch_related()函数中的模型实例字段(使用make_json())从您的._meta.get_fields()ForeignKey字段中排除序列化。

答案 1 :(得分:0)

您正在寻找的是QuerySet的defer()only()方法。
defer() - 省略从数据库中检索的字段。
only() - 仅返回数据库中的指定字段。

在你的情况下: FooBar.objects.defer('cats', 'dogs').filter(...)

https://docs.djangoproject.com/en/1.11/ref/models/querysets/#django.db.models.query.QuerySet.defer

答案 2 :(得分:-1)

所以...经过几个小时的思考,这就是我得到的:

# Getting list of model fields
# and excluding cats and dogs from this list.
result_fields = [f.name for f in FooBar._meta.get_fields()]
result_fields.remove('cats')
result_fields.remove('dogs')

# Making query.
FooBar.objects.values(*result_fields).filter(....)

返回python dict而不是QuerySet有一件坏事,但对于很多情况来说这可能已经足够了。