【问题标题】:How should I change the path in "urlpatterns"?我应该如何更改“urlpatterns”中的路径?
【发布时间】:2019-09-28 23:10:59
【问题描述】:

我正在尝试创建一个博客,并希望文章按类别划分。 Django 版本:2.1,Python:3.7 我不明白如何更改 urlpatterns 中的路径以显示类别名称,而不是 <int:pk>。在哪里可以查看 Django 代码示例?

我试图做 path('category.title') 但它不起作用。

这是我的models.py:

from django.db import models
from django.conf import settings
from django.urls import reverse

class Category(models.Model):
    title = models.CharField(max_length=50)
    image = models.ImageField(upload_to='', blank=True)

    def __str__(self):
        return self.title

class Article(models.Model):
    title = models.CharField(max_length=255)
    body = models.TextField()
    date = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE
    )
    image = models.ImageField(upload_to='', blank=True)
    cat = models.ForeignKey(
        Category, on_delete=models.CASCADE, null=True,
    )

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('article_detail', args=[str(self.id)])

class Comment(models.Model):
    article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='comments')
    comment = models.CharField(max_length=100)
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )

    def __str__(self):
        return self.comment

    def get_absolute_url(self):

     return reverse('article_list')

这是 urls.py:

from django.urls import path
from . import views
from .models import Category

urlpatterns = [
    path('', views.ArticleViewList.as_view(), name='article_list'),
    path('<int:pk>/edit/', views.ArticleUpdateView.as_view(), name='article_edit'),
    path('<int:pk>/delete/', views.ArticleDeleteView.as_view(), name='article_delete'),
    path('<int:pk>', views.ArticleDetailView.as_view(), name='article_detail'),
    path('new/', views.ArticleCreateView.as_view(), name='article_new'),
]

这是返回文章列表的基于类的视图:

 class ArticleViewList(LoginRequiredMixin, ListView):
    model = models.Article
    template_name = 'article_list.html'
    login_url = 'login'

1)我希望在地址栏中显示类别的标题 2)我想知道使用基于类的视图是一个好的决定 3)我想知道如何在模板循环中显示特定类别的文章

【问题讨论】:

标签: python django django-models django-templates django-views


【解决方案1】:

希望您的网址看起来像:
/ - 所有帖子的列表,无论类别如何
/category1 - 类别 1 中的所有帖子的列表
/category1/1 - 详细信息帖子 #1(可选,必须或不得属于 category1)

你需要做几件事:
1) 您需要将 SlugField 添加到您的类别模型中 - 这是 url 中的实际字符串,因为对 url 中的内容有一些限制。

models.py:

class Category(models.Model):
    title = models.CharField(max_length=50)
    slug = models.SlugField(unique=True)
    image = models.ImageField(upload_to='', blank=True)

    def __str__(self):
        return self.title

2) 修改urlpatterns 为需要slug

urls.py:

urlpatterns = [
    path('', ArticleViewList.as_view(), name='article_list'),
    path('<slug:catslug>', ArticleViewList.as_view(), name='article_list'),
    path('<slug:catslug>/<int:pk>', ArticleDetailView.as_view(), name='article_detail'),
]

3) 为您的ArticleViewList 添加查询集过滤器,这样您就只会按其 slug 字段值包含来自特定类别的文章。

views.py:

from django.shortcuts import get_object_or_404

class ArticleViewList(LoginRequiredMixin, ListView):
    model = Article
    template_name = 'article_list.html'
    login_url = 'login'

    def get_queryset(self):
        queryset = super().get_queryset()
        if 'catslug' in self.kwargs:
            category_slug = self.kwargs['catslug']
            category = get_object_or_404(Category, slug=category_slug)
            queryset = queryset.filter(cat=category)
        return queryset

4) (可选)也可以通过修改查询集来强制检查您的文章详细信息视图是否属于 url 中的某个类别。

views.py:

class ArticleDetailView(LoginRequiredMixin, DetailView):
    model = Article
    template_name = 'article_item.html'
    login_url = 'login'

    def get_queryset(self):
        queryset = super().get_queryset()
        category_slug = self.kwargs['catslug']
        category = get_object_or_404(Category, slug=category_slug)
        queryset = queryset.filter(cat=category)
        return queryset

使用 CBV 是一个不错的决定 - 因为您的所有视图都很简单,并且正是 CBV 的设计目的。它将允许您拥有小而易读的代码。

您可以使用{% regroup %}按类别对文章进行分组:

article_list.html:

{% regroup object_list by cat as categories %}

{% for category in categories %}
    {{ category.grouper }}:</br>
    {% for object in category.list %}
        {{ object }}<br>
    {% endfor %}
{% endfor %}

【讨论】:

  • Спасибо большое за помощь! Единственный вопрос, что такое self.kwargs ?
  • @KochetovMXM 它是基于名称的属性,在这种情况下用于动态填充。你可以阅读更多关于django docs
  • Подскажи пожалуйста, как ты учил джанго и сколько времени это заняло?
  • 一周开始并关注official django tutorial。在 django 之前我有一些背景。 Django 有很棒的文档,你可以用 google 搜索大部分问题,而且在实践中更容易学习。
【解决方案2】:

使用基于类的视图很好,但也使用函数视图也可以正常工作,实际上在这种情况下使用函数,但您可以更改一些内容,并且也适用于基类。只要您知道自己想要什么,它们的工作方式几乎相同。关于的问题 在这里使用链接中的标题而不是主键。

django 将通过将 url 中的空格和特殊字符编码为安全格式来转义它,但仍然可以理解它。这就是为什么我认为与使用唯一 ID 相比,这个想法不是最好的,但如果你仍然需要它,

也许你的网址中需要这样的东西

from django.conf.urls import url
url(regex=r'^(?P<category>[\w ]+)/$', view=category_article, name='category_articles'),

在你看来

from.models import Category, Article
def category_article(request, category):
    cat = Category.objects.get(title=category)
    categories = Category.objects.all()
    articles_in_category = Article.objects.filter(cat=cat)

    context = {
   'categories':categories,
   'articles':articles_in_category,
    }
    // render this two now to template
   //I could not coz I dont know path to your template


当你想建立一个链接时,你会使用标题来代替

{% for category in categories %}
<a href="{% url 'category_articles' category.title %}">{{category.title}}</a>
{% endfor %}

或者如果您想使用文章来指向其类别的其他元素元素

{% for article in articles %}
<a href="{% url 'category_articles' article.cat.title %}">{{category.title}}</a>
{% endfor %}

你的问题对我来说不是很清楚,但希望我能回答你的测验,

【讨论】:

  • 欢迎,希望你找到解决办法
猜你喜欢
  • 2019-06-21
  • 2020-05-05
  • 2012-03-21
  • 2020-08-25
  • 1970-01-01
  • 1970-01-01
  • 2021-04-04
  • 1970-01-01
  • 2014-05-08
相关资源
最近更新 更多