python - 如何在 django 的 url 上放置搜索查询?
问题描述
我正在使用 Django 创建一个搜索应用程序。
我做了一个文章模型和一个记录文章评分的反馈模型。
进入搜索框并显示搜索结果后,单击其中一个结果,然后转到详细信息屏幕。
在详细屏幕上选择反馈并按下提交按钮后,我想将搜索查询保存到反馈模型。
我认为解决方案是在 URL 中添加一个查询portal/search/?=query
并阅读它,但我不知道如何编码。另外,能否教教我URL中除了读取查询之外是否还有其他实现方法?
此外,当我从详细屏幕返回时,我也想显示以前的搜索结果。
如果您有任何问题,请发表评论。原谅我糟糕的英语。
模型.py
from django.db import models
from django.urls import reverse
from taggit.managers import TaggableManager
class KnowHow(models.Model):
BASIC_TAGS =(
('1','one'),
('2','two'),
('3','three'),
('4','four'),
('5','five'),
('6','six'),
)
CATEGORY =(
('1','Type2'),
('2','Type1'),
)
author = models.ForeignKey('auth.User',on_delete=models.CASCADE)
category = models.CharField(max_length=1,choices=CATEGORY,default='1')
title = models.CharField(max_length=200)
text = models.TextField(blank=True,default=' ')
# delault=' ':import system will give a error if text column is null
file = models.FileField(blank=True,upload_to='explicit_knowhows')
basic_tag = models.CharField(max_length=1,choices=BASIC_TAGS,default='1')
free_tags = TaggableManager(blank=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('portal:index')
class Feedback(models.Model):
EFFECT =(
('1','great'),
('2','maybe good'),
('3','bad'),
)
NOVEL =(
('1','I didn't know that'),
('2','I know, but I forgot'),
('3','I know this.'),
)
kh = models.ForeignKey(KnowHow, on_delete=models.PROTECT)
user = models.ForeignKey('auth.User',on_delete=models.CASCADE)
query = models.TextField(blank=True)
time = models.DateTimeField(auto_now_add=True)
efficacy = models.CharField(max_length=1,choices=EFFECT,default='1')
novelty = models.CharField(max_length=1,choices=NOVEL,default='1')
def __str__(self):
return self.time.strftime("%Y/%m/%d %H:%M:%S")
视图.py
from django.urls import reverse, reverse_lazy
from django.http import HttpResponse
from django.views import generic
from django.views.generic.edit import ModelFormMixin
from django.shortcuts import redirect,get_object_or_404
from django.core.exceptions import PermissionDenied
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.decorators import login_required
from .models import KnowHow
from taggit.models import Tag
from .forms import SearchForm,FeedbackForm
from django.db.models import Q
"""
Django Auth
The LoginRequired mixin
https://docs.djangoproject.com/en/2.0/topics/auth/default/#the-loginrequired-mixin
The login_required decorator
https://docs.djangoproject.com/en/2.0/topics/auth/default/#the-login-required-decorator
@login_required
"""
class IndexView(LoginRequiredMixin,generic.list.ListView):
model = KnowHow
#paginate_by = 5
ordering = ['-title']
# template_name = 'portal/KnowHow_list.html'
class DetailView(ModelFormMixin,LoginRequiredMixin,generic.detail.DetailView):
# from https://torina.top/detail/337/
model = KnowHow
form_class = FeedbackForm
template_name = 'portal/KnowHow_detail.html'
def form_valid(self, form):
kh_pk = self.kwargs['pk']
Feedback = form.save(commit=False)
Feedback.kh = get_object_or_404(KnowHow, pk=kh_pk)
Feedback.query=""
Feedback.user=self.request.user
Feedback.save()
return redirect('portal:search')
def post(self, request, *args, **kwargs):
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
self.object = self.get_object()
return self.form_invalid(form)
class CreateView(LoginRequiredMixin, generic.edit.CreateView): # The LoginRequired mixin
model = KnowHow
fields = ['category','title','text','file','basic_tag','free_tags']
#template_name = 'portal/KnowHow_form.html'
def form_valid(self, form):
# This method is called when valid form data has been posted.
# It should return an HttpResponse.
# https://docs.djangoproject.com/en/2.0/topics/class-based-views/generic-editing/#models-and-request-user
form.instance.author = self.request.user
return super(CreateView, self).form_valid(form)
class UpdateView(LoginRequiredMixin, generic.edit.UpdateView): # The LoginRequired mixin
model = KnowHow
fields = ['category','title','text','file','basic_tag','free_tags']
#template_name = 'portal/KnowHow_form.html'
class DeleteView(LoginRequiredMixin, generic.edit.DeleteView): # The LoginRequired mixin
model = KnowHow
success_url = reverse_lazy('portal:index')
def delete(self, request, *args, **kwargs):
result = super().delete(request, *args, **kwargs)
Tag.objects.filter(knowhow=None).delete()
return result
#template_name = 'portal/KnowHow_confirm_delete.html'
class SearchIndexView(LoginRequiredMixin, generic.ListView):
template_name="search/search_index.html"
model = KnowHow
def post(self, request, *args, **kwargs):
form_value = [
self.request.POST.get('basic_tag', None),
self.request.POST.get('free_tags', None),
]
request.session['form_value'] = form_value
self.request.GET = self.request.GET.copy()
self.request.GET.clear()
return self.get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
basic_tag = ''
free_tags = ''
if 'form_value' in self.request.session:
form_value = self.request.session['form_value']
basic_tag = form_value[0]
free_tags = form_value[1]
default_data = {'basic_tag': basic_tag,
'free_tags': free_tags,
}
test_form = SearchForm(initial=default_data)
context['test_form'] = test_form
return context
def get_queryset(self):
if 'form_value' in self.request.session:
form_value = self.request.session['form_value']
basic_tag = form_value[0]
free_tags = form_value[1]
condition_basic_tag = Q()
condition_free_tags = Q()
if len(basic_tag) != 0 and basic_tag[0]:
condition_basic_tag = Q(basic_tag=basic_tag)
if len(free_tags) != 0 and free_tags[0]:
condition_free_tags = Q(free_tags__name__in=free_tags)
return KnowHow.objects.filter(condition_basic_tag & condition_free_tags).distinct()
else:
return KnowHow.objects.none()
@login_required
def help(request):
return HttpResponse("Member Only Help Page")
网址.py
from django.urls import path
from . import views
# set the application namespace
# https://docs.djangoproject.com/en/2.0/intro/tutorial03/
app_name = 'portal'
urlpatterns = [
# ex: /
path('', views.IndexView.as_view(), name='index'),
# ex: /KnowHow/create/
path('KnowHow/create/', views.CreateView.as_view(), name='create'),
# ex: /KnowHow/1/
path('KnowHow/<int:pk>/detail/', views.DetailView.as_view(), name='detail'),
# ex: /KnowHow/1/update/
path('KnowHow/<int:pk>/update/', views.UpdateView.as_view(), name='update'),
# ex: /KnowHow/1/delete
path('KnowHow/<int:pk>/delete/', views.DeleteView.as_view(), name='delete'),
# ex: /KnowHow/help/
path('KnowHow/help/', views.help, name='help'),
path('search/',views.SearchIndexView.as_view(), name='search')
]
解决方案
您的问题有几种解决方案。
- 第一个是您自己提到的确切解决方案。使用查询字符串参数,例如
?q=
详细KnowHow
信息视图。 - 使用
SearchLog
模型并使用该模型的标识符。当有人点击/search/
端点时,您创建一个新SearchLog
的并将pk
此记录传递到您的前面。基本上它就像?q=
选项一样。相反,您可以使用?search_id=
将反馈绑定到特定的SearchLog
- 使用用户会话。将搜索到的查询绑定到用户的会话,当他们想要创建一个新
Feedback
的时,query
在他们的会话中使用。
对于前两个选项,您只需要正确创建详细链接的网址(在您的搜索结果页面中)。在您的模板中,执行以下操作:
# You are probably doing something like this
{% for r in results %}
<a href="{{r.absolute_url}}">{{r.name}}</a>
{% endfor %}
# You should do this instead
{% for r in results %}
<a href="{{r.absolute_url}}{{current_query}}">{{r.name}}</a>
{% endfor %}
您可以在渲染模板时传入current_query
您context
的值,也可以使用 javascript 从浏览器的location / query string
.
推荐阅读
- powershell - 学生,在创建新用户 powershell 时自动向管理员发送电子邮件
- c++ - 调试模板的问题。专门针对 Linux GCC 7、GCC 6、GCC 5、GCC 4.9 错误的构建失败:模板参数 1 无效
- azure - 如何在单个事务中将一组用于 OCR 分析的图像提交到 Azure 计算机视觉 API?
- java - SAML Java Sping Boot - PKIX 路径构造因不受信任的凭证而失败
- python - 未同时运行的线程一次运行 1 个 Python
- c# - 尝试在 C# 中生成 hardwareID 并获得“System.Management.ManagementPath”异常
- php - Illuminate\Routing\Controller 或 App\Http\Controllers\Controller
- r - R中有没有办法覆盖3个密度图,以时间为x轴,以时间为y轴?
- python - 按熊猫分组并按值替换空值
- android-context - Toast 反复打印