gpt4 book ai didi

python - Django : global search in different model - Post result does not appears

转载 作者:行者123 更新时间:2023-12-03 18:34:11 26 4
gpt4 key购买 nike

我希望你很好。我在不同的应用程序中创建了一个具有多个模型的全局搜索。
后期模型属于 Nutriscore 文件夹
UserProfile 模型属于 User 文件夹
如果我使用一个涵盖 Post 和 UserProfile 搜索的词,例如 Main course。我得到了 UserProfile 的一些搜索结果(3 个结果),但 Post 没有出现(而 count 给了我 6 个结果)。所以我不知道代码有什么问题?
用户/ View .py

 # global search 
class GlobalSearchView(ListView):
template_name = 'search_global.html'
count = 0
countnutri = 0

def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['count'] = self.count or 0
context['countnutri'] = self.countnutri or 0
context['query'] = self.request.GET.get('q')
return context

def get_queryset(self): # new
query = self.request.GET.get('q', None)
if query is not None:
nutriscore = Post.objects.filter(
Q(title__icontains=query) | Q(slug__icontains=query) | Q(typederepas__name__icontains=query) | Q(prixrepas__name__icontains=query) | Q(vitesserepas__name__icontains=query) | Q(force__name__icontains=query) | Q(bienfaitrepas__name__icontains=query)
).distinct()
user = UserProfile.objects.filter(
Q(pays__icontains=query) | Q(town__icontains=query) | Q(user__username__icontains=query) | Q(mealtrend__name__icontains=query) | Q(pricetrend__name__icontains=query) | Q(speedtrend__name__icontains=query)| Q(strengthtrend__name__icontains=query) | Q(wellnesstrend__name__icontains=query)
).distinct()
results = chain(nutriscore,user)

qs = sorted(user,
key=lambda instance: instance.pk,
reverse=True)
self.count = len(qs)

qn = sorted(nutriscore,
key=lambda instance: instance.pk,
reverse=True)
self.countnutri = len(qn)

return qs
return qn
return results



用户/网址.py
path('search/', GlobalSearchView.as_view(),name="global_search"),
用户/模板/global_search.html
我在 css 中得到了一个带有显示/折叠功能的菜单。
<div class="row" id="collapseNutriscore">
{% for object in object_list %}
{% with object|class_name as klass %}
{% if klass == 'Post' %}


{{ object.title }}



{% endif %}
{% endwith %}
{% endfor %}
</div>

<br>
<br>

<div class="row collapse" id="collapseCooker">
{% for object in object_list %}
{% with object|class_name as klass %}
{% if klass == 'UserProfile' %}


{{ object.user.username }}



{% endif %}
{% endwith %}
{% endfor %}

</div>

最佳答案

免责声明: 这个答案可能不适合 OP 的 View 或模型,但是,它可以按原样与示例一起使用。
为了清楚起见,我假设我们有两个模型,MusicianAlbum,它们位于 sample 应用程序中。

# sample/models.py

from django.db import models


class Musician(models.Model):
name = models.CharField(max_length=50)

def __str__(self):
return f'{self.name}'


class Album(models.Model):
artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
description = models.TextField()

def __str__(self):
return f'{self.name} : {self.artist}'
然后,我们必须创建一个 mixin 类,以获得更好的 OOP 体验以及跨多个 View 的可扩展性。
#sample/mixins.py

from django.apps import apps
from django.db.models import Q
from functools import reduce
from operator import or_


class SearchMixin:
search_keyword_arg = 'q'
search_settings = {}
lookup_expr = 'icontains'

def get_search_term(self):
return self.request.GET.get(self.search_keyword_arg)

def build_search_query(self, model_ref, term):
return reduce(or_, [Q(**{f'{field}__{self.lookup_expr}': term}) for field in self.search_settings[model_ref]])

def get_search_results(self):
has_search_result = False
search_term = self.get_search_term()
if not search_term:
return {'has_search_result': has_search_result}

results = {}

for model_ref, fields in self.search_settings.items():
app_name, model_str = model_ref.split('.')
ModelKlass = apps.get_model(app_label=app_name, model_name=model_str)
qs = ModelKlass.objects.filter(self.build_search_query(model_ref, search_term))
results[model_ref.replace('.', '_').lower()] = qs
if has_search_result is False and qs.exists():
has_search_result = True

results['has_search_result'] = has_search_result
return results

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['search_result'] = self.get_search_results()
return context
这个 SearchMixin 类具有我们想要的搜索功能。我们可以将此类添加到任何 Django View 中以获取结果。
为此,我们将 SearchMixin 类继承为 ListView 为,
# sample/views.py

from django.views.generic import TemplateView
from sample.mixins import SearchMixin


class GlobalSearchView(SearchMixin, TemplateView):
template_name = 'sample/global_search.html'
search_settings = {
'sample.Musician': ['name'],
'sample.Album': ['name', 'description'],
}

注释:
  • 我使用了 TemplateView ,它更适合这种特殊情况。
  • 有一个名为 search_settings 的新类属性,用于确定搜索字段。

  • search_settings 属性应该如何?
  • 必须是 dict(或 dict 之类的对象)
  • dict 对象的 key 应该是 app_name.ModelClassName 格式
  • dict
  • 值必须是可迭代的模型字段

  • 在模板中看起来如何?
    SearchMixin 类将搜索结果添加到名为 search_result 的上下文变量中,该变量具有另一个变量 has_search_result ( search_result.has_search_result ),可用于检查我们是否有“任何匹配”。
    此外,每个 QuerySet 都可以通过单独的变量访问。变量的格式是,
    app_name<underscore><model_name_in_lower_case>
    例如,对于 sample.Musician模型,可以在模板中获取搜索结果(如果有的话), {{ search_result.sample_musician }}
    # sample/templates/sample/global_search.html

    {% if search_result.has_search_result %}
    <strong>Musician result</strong><br>
    {% for musician in search_result.sample_musician %}<br>
    {{ musician.name }}
    {% endfor %}
    <br><br>
    <strong>Album result</strong><br>
    {% for album in search_result.sample_album %}
    {{ album.name }} -- {{ album.description }}<br>
    {% endfor %}
    {% else %}
    No match
    {% endif %}
    现在,连接 urls.py 中的 View 并使用查询参数作为搜索,
    /foo-bar/global-search/?q=xx

    关于python - Django : global search in different model - Post result does not appears,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63601113/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com