【发布时间】:2020-09-02 12:23:13
【问题描述】:
我正在尝试模拟 Google 的行为,其中用户在浏览器的地址栏上键入内容,而 Django 服务器检查数据库中的任何精确匹配项。如果是这样,则呈现对象的详细视图。如果不是完全匹配,则使用 ListView 呈现子字符串上的匹配列表。
当用户在搜索表单中键入内容时,此行为可以正常工作。例如,当用户在搜索表单中输入字母 'j' 并点击提交时,Django 服务器会匹配数据库 'Django 中的 3 个对象, Java, node.js' 并通过 ListView 渲染这个列表。如果存在完全匹配,假设用户键入了“java”,那么 Django 服务器会在详细信息视图中呈现有关对象“java”的详细信息。
但是,当应用于用户在浏览器地址栏上键入的内容时,我无法弄清楚如何得出相同的行为。如果用户碰巧在 db 中键入了项目的准确拼写,则会呈现项目的详细信息,否则会出现 404 错误。
下面展示html表单、urls.py、views.py的相关段
<form method="GET" action="{% url 'searchwiki' %}">
<input class="search" type="text" name="q" placeholder="Search Encyclopedia">
</form>
urls.py:
urlpatterns = [
path("", views.EntryListView.as_view(), name="index"),
path("entries/",views.EntryListView.as_view(),name='entries'),
path("entry/<int:pk>",views.EntryDetailView.as_view(),name="entry_detail"),
path("<int:pk>", views.EntryDetailView.as_view(), name="path_entry-detail"),
# path("<slug:subject>",views.get_obj_orlist),
path("<slug:subject>",views.EntryDetailView.as_view()),
path("random/",views.randompage,name="randompage"),
path("searchwiki/",views.searchwiki,name="searchwiki"),
]
views.py:
from django.urls import path
from . import views
from .models import Entry
from django.shortcuts import get_object_or_404, render, redirect
from django.views import generic
from django.views.generic.edit import CreateView, UpdateView, DeleteView
def searchwiki(request):
searchtoken = request.GET.get('q')
try:
entry = Entry.objects.get(subject=searchtoken)
except Entry.DoesNotExist:
entries = Entry.objects.filter(subject__icontains=searchtoken)
print("Inside exception code. qset size is ",len(entries))
return render(request, 'wikiencyc/searchencyc.html','entries':entries,'searchtoken':searchtoken})
return redirect(entry)
def get_obj_orlist(request):
model = Entry
slug_field = 'subject'
slug_url_kwarg = 'subject'
# below is the solution if it works
slug = kwargs.get(slug_url_kwarg)
try:
entry = Entry.objects.get(subject=slug)
except Entry.DoesNotExist:
entries = Entry.objects.filter(subject__icontains=slug)
return render(request, 'wikiencyc/searchencyc.html', {'entries':entries,'searchtoken':slug} )
return redirect(entry)
class EntryDetailView(generic.DetailView):
model = Entry
slug_field = 'subject'
slug_url_kwarg = 'subject'
urls.py 中的“searchwiki/”路径和 views.py 中的 searchwiki(request) 函数完美地协同工作,以响应搜索表单。
至于从地址栏中解析 slug,EntryDetailView(generic.DetailView) 可以完美匹配数据库中已解析的 slug,但会以 404 异常响应屏幕而不是列表子字符串匹配。
我尝试为地址栏复制 searchwiki 函数是函数 get_obj_orlist(request)。它失败了,因为我无法弄清楚如何从地址栏和 urlconf 获取 slug 到所述函数。这可能是一件非常简单的事情,但是在搜索了 Django 服务器代码和文档 2 天后,我说 AARRGG !!!当我看到 args 和 kwargs 时。任何帮助都深表感谢。我仍在为正则表达式苦苦挣扎,所以如果在解决方案演示中可以避免这些,我将不胜感激。
【问题讨论】:
-
请正确格式化您的代码
-
@ArakkalAbu 我很抱歉。这是我第一次在网站上发布代码。
-
如果你得到一个不存在的 404,这意味着
wikiencyc/searchencyc.htmldoesn 不存在......你的调试日志说它在寻找什么?旁注:我通常避免像这样直接渲染模板,而是通过reverseurl 查找和视图来完成——它更容易维护,但本质上是个人选择。 -
@urbanespaceman 上述模板 html 文件确实存在。我将问题缩小到如何从用户在地址栏中输入的 url 访问解析的 slug 信息。如果用户键入 127.0.0.1:8000/wikiencyc/java ,通用 DetailView 代码可以解析最后的“java”部分,并将其作为 slug 分配给视图类代码中的“主题”关键字。如果用户只是在 slug 的末尾键入“j”,它会返回 404 错误,因为 db 中没有完全匹配。我缺乏的知识是如何解析 slug 并将其作为参数传递给视图。