【问题标题】:Django: How to parse slug from url typed in address bar?Django:如何从地址栏中输入的 url 解析 slug?
【发布时间】: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 不存在......你的调试日志说它在寻找什么?旁注:我通常避免像这样直接渲染模板,而是通过reverse url 查找和视图来完成——它更容易维护,但本质上是个人选择。
  • @urbanespaceman 上述模板 html 文件确实存在。我将问题缩小到如何从用户在地址栏中输入的 url 访问解析的 slug 信息。如果用户键入 127.0.0.1:8000/wikiencyc/java ,通用 DetailView 代码可以解析最后的“java”部分,并将其作为 slug 分配给视图类代码中的“主题”关键字。如果用户只是在 slug 的末尾键入“j”,它会返回 404 错误,因为 db 中没有完全匹配。我缺乏的知识是如何解析 slug 并将其作为参数传递给视图。

标签: python django


【解决方案1】:

我找到了解决方案。正如我所料,这是一个非常微不足道的忽视。只需将主题作为参数包含在函数中,就可以在 Entry 模型中用于查询目的。工作函数如下所示。

def get_obj_orlist(request, subject):
model = Entry
try:
    entry = Entry.objects.get(subject=subject)
except Entry.DoesNotExist:
    entries = Entry.objects.filter(subject__icontains=subject)
    return render(request, 'wikiencyc/searchencyc.html', {'entries':entries,'searchtoken':subject} )
return redirect(entry)

【讨论】:

    猜你喜欢
    • 2020-09-18
    • 2014-10-12
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 1970-01-01
    • 2013-04-02
    • 2014-07-11
    • 1970-01-01
    相关资源
    最近更新 更多