查询Django模板中的M2M关系

时间:2021-02-08 14:38:43

I have a Document model which has a many to many "favorites" relationship to User. When I display a list of Documents on the search page I would like to show whether each document is a favorite or not for the current user. I know two ways of doing this, one more efficient and one cleaner. I am wondering if there is another way I can do it so that it's both efficient and clean.

我有一个Document模型,它与User有很多“最爱”关系。当我在搜索页面上显示文档列表时,我想显示每个文档是否是当前用户的最爱。我知道这样做的两种方式,一种更有效,一种更清洁。我想知道是否有其他方法可以做到这一点,以便它既高效又干净。

  1. Clean version. Simply have a method on the model "is_favored(user)" that tells whether the document is favored by the given user. Then have a simple template tag that uses this function to display an empty star or a filled star. Of course this is not efficient since it would make a different DB call for each document. But it's nice because the view does not have to be changed in any way.

    清洁版。只需在模型“is_favored(user)”上有一个方法,它告诉文档是否受给定用户的青睐。然后有一个简单的模板标签,使用此功能显示空星或填充星。当然这没有效率,因为它会为每个文档进行不同的DB调用。但它很好,因为视图不必以任何方式改变。

  2. Efficient version. Do a single database query in the view to retrieve the favorite queries and add a "favored" field on each Document. I don't like this approach because I will have to add custom code to all views that display Documents and it's not too DRY.

    高效版。在视图中执行单个数据库查询以检索收藏查询并在每个文档上添加“favored”字段。我不喜欢这种方法,因为我必须为显示文档的所有视图添加自定义代码,并且它不太干。

Is there a better approach that is both DRY and efficient? Thanks.

是否有更好的方法既干又有效?谢谢。

1 个解决方案

#1


1  

Context processors are what you are looking for.

上下文处理器是您正在寻找的。

Here you can read about it: http://www.djangobook.com/en/2.0/chapter09.html (check out RequestContext and Context Processors section)

在这里你可以阅读它:http://www.djangobook.com/en/2.0/chapter09.html(查看RequestContext和Context Processors部分)


edit:

You can also simply create a function that takes user and list of documents currently displayed in search results. Something like this:

您还可以简单地创建一个功能,该功能将用户和当前显示在搜索结果中的文档列表。像这样的东西:

def favs(user, docs):
    l = user.favorites.filter(pk__in=docs).values_list('pk', flat=True)
    return dict( (k, (k in l)) for k in docs )

So now, we have dictionary that says if document with given id is favorite or not. And then call that function in each view and use its results.

所以现在,我们有字典说明具有给定id的文档是否是最喜欢的。然后在每个视图中调用该函数并使用其结果。

It is DRY now (cause if you want to change f.e. name of attribute "favorites" you have to do only one change.

它现在是DRY(因为如果你想改变f.e.属性“收藏夹”的名称,你只需要进行一次更改。

#1


1  

Context processors are what you are looking for.

上下文处理器是您正在寻找的。

Here you can read about it: http://www.djangobook.com/en/2.0/chapter09.html (check out RequestContext and Context Processors section)

在这里你可以阅读它:http://www.djangobook.com/en/2.0/chapter09.html(查看RequestContext和Context Processors部分)


edit:

You can also simply create a function that takes user and list of documents currently displayed in search results. Something like this:

您还可以简单地创建一个功能,该功能将用户和当前显示在搜索结果中的文档列表。像这样的东西:

def favs(user, docs):
    l = user.favorites.filter(pk__in=docs).values_list('pk', flat=True)
    return dict( (k, (k in l)) for k in docs )

So now, we have dictionary that says if document with given id is favorite or not. And then call that function in each view and use its results.

所以现在,我们有字典说明具有给定id的文档是否是最喜欢的。然后在每个视图中调用该函数并使用其结果。

It is DRY now (cause if you want to change f.e. name of attribute "favorites" you have to do only one change.

它现在是DRY(因为如果你想改变f.e.属性“收藏夹”的名称,你只需要进行一次更改。