如何更改“ urlpatterns”中的路径?

时间:2019-05-11 06:27:10

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

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

我尝试执行path('category.title'),但是它不起作用。

这是我的模型。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)我想知道如何在模板循环中显示特定类别的文章

2 个答案:

答案 0 :(得分: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添加查询集过滤器,因此您将仅按其类别字段值包括特定类别的文章。

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 %}

答案 1 :(得分:0)

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

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 %}

您对我的问题不太清楚,但希望我能回答您的测验,