django - 使用 Q 对象行为应用自定义 mixin 和查找
问题描述
我有以下 mixin,我想在其中检索用户模型数据以将这些数据放在我正在开发的不同基于类的视图中:
class UserProfileDataMixin(object):
def get_context_data(self, **kwargs):
context = super(UserProfileDataMixin, self).get_context_data(**kwargs)
user = self.request.user
#context['userprofile'] = user.profile
if user.is_authenticated():
context['userprofile'] = user.profile
return context
然后,我有以下搜索视图,其中我根据以下条件使用 Q 对象查找用户:
当我们通过username
和full_name
字段搜索时
class SearchView(UserProfileDataMixin, ListView):
template_name = 'search.html'
def get(self, request, *args, **kwargs):
query = request.GET.get("q")
qs = None
if query:
qs = User.objects.filter(
Q(username__icontains=query) |
Q(full_name__icontains=query)
)
context = {"users": qs}
return render(request, "search.html", context)
当我从UserProfileDataMixin
这个 mixin 继承时,我可以将userprofile
上下文变量传递给我的search.html
模板,该模板继承自layout.html
模板,我在其中执行以下验证:
search.html 模板
{% extends "layout.html" %}
layout.html 模板
{% if userprofile %}
I put the data of user by example:
avatar, username, full_name, and menu options to my app.
{% endif %}
直到这里,一切都好,但我的基于类的视图SearchView
不适用,UserProfileDataMixin
因为我无法在我的模板上获取用户数据,这些数据来自layout.html
.
当我得到搜索用户模板时,我得到了:
我稍微改变了基于类的视图SearchView
,覆盖了get_queryset
方法而不是get
方法 a
class SearchView(UserProfileDataMixin, ListView):
template_name = 'search.html'
def get_queryset(self):
query = self.request.GET.get("q")
qs = None
if query:
qs = User.objects.filter(
Q(username__icontains=query) |
Q(full_name__icontains=query)
)
context = {"users": qs}
return render(self.request, "search.html", context)
我的基于类的视图SearchView
应用了,因为我可以从我的模板UserProfileDataMixin
中获取用户数据。layout.html
现在出现我带来的顶部标题菜单 UserProfileDataMixin
但是我现在有我的 Q 查找查询不起作用的不便
为什么当我覆盖方法时UserProfileDataMixin
不应用于我的基于类的视图但如果当我覆盖方法时,但这会消除我的自定义查找 q 对象查询的影响?SearchView
get
get_queryset
我应该什么get
时候使用,什么时候使用get_queryset
?
在这个答案问题中解释了这个主题,我认为使用get_queryset
是合适的,但是,为什么我的查询没有以与我使用方法时相同的方式执行get
?为什么使用 get 方法 myUserProfileDataMixin
不是继承的?
解决方案
为您get()
调用的基本实现。get_context_data()
但是,因为您已经用自己的实现覆盖了,所以您get()
需要调用get_context_data()
自己。
class SearchView(UserProfileDataMixin, ListView):
template_name = 'search.html'
def get(self, request, *args, **kwargs):
query = request.GET.get("q")
qs = None
if query:
qs = User.objects.filter(
Q(username__icontains=query) |
Q(full_name__icontains=query)
)
# Get the context data from the base class (mixin) and update it
context = super(SearchView, self).get_context_data()
context["users"] = qs
return render(request, "search.html", context)
但是,更好的解决方案可能是根本不覆盖get()
,并get_context_data()
在您的SearchView
. 例如
class SearchView(UserProfileDataMixin, ListView):
template_name = 'search.html'
def get_context_data(self, **kwargs):
query = self.request.GET.get("q")
qs = None
if query:
qs = User.objects.filter(
Q(username__icontains=query) |
Q(full_name__icontains=query)
)
context = super(SearchView, self).get_context_data(**kwargs)
context["users"] = qs
return context
最后,您的get_queryset()
实现没有做正确的事情,因为该方法旨在返回 QuerySet 对象,而在您的情况下,它正在呈现模板。
推荐阅读
- python - 为什么这种多线程比单线程慢
- python - 将 2 列表转换为包含整个列表的字典列表
- skip - ASP.Net MVC Paging 返回一个大的结果集,而不是将结果集拆分为页面
- javascript - 如何使用此代码放大照片库页面中的多个图像
- sql - 如何将我的 SQL 查询转换为 LINQ 语句
- javascript - 如何使用jquery设置滚动高度
- c++ - 为什么通过 char 向量进行迭代比通过 C++ 中的字符串进行迭代更快
- c++ - 如何将这种快速排序转换为降序?
- smartcard - ATS(Answer-to-Select)通过非接触式或 NFC 与 ATR(Answer-to-Reset)通过接触卡的区别
- rxjs - 重试运算符使用可观察但不使用主题