Django 2:网址中有多个子弹

时间:2019-02-18 13:41:44

标签: python django

我目前正在关注sentdex的django教程。本教程将克隆https://pythonprogramming.net/。在本教程中,他在URL中仅使用一个Slug,但我认为拥有多个Slug更为方便,因为URL会更有条理。例如,指向pythonprogramming.net上的教程的链接如下所示:https://pythonprogramming.net/build-supercomputer-raspberry-pi/。我希望它在项目中的外观为mydomain.com/data-analsyis/build-supercomputer/1/。该网址将是domain/category/series/episode/,而不是domain/episode/

# urls.py
from django.urls import path
from . import views

app_name = "main"

urlpatterns = [
    path('', views.homepage, name="homepage"),  # View categories
    path("register/", views.register, name="register"),
    path("logout/", views.logout_request, name="logout"),
    path("login/", views.login_request, name="login"),
    path("<slug:series_slug>/", views.slugs, name="series_blocks"),  # Views all the series in that category
    path("<slug:series_slug>/<slug:tutorial_slug>/", views.slugs, name="tutorial_blocks"),  # View all tutorials in series
    path("<slug:series_slug>/<slug:tutorial_slug>/<int:id>/", views.slugs, name="tutorial_blocks"),  # View spesific tutorial nr.
]

注意::我认为最好有3种不同的功能,而不是views.slug

# Models.py
from django.db import models
from datetime import datetime


class TutorialCategory(models.Model):
    category = models.CharField(max_length=100)
    summary = models.CharField(max_length=200)
    slug = models.CharField(max_length=100)

    class Meta:
        verbose_name_plural = "Kategorier"

    def __str__(self):
        return self.category


class TutorialSeries(models.Model):
    series = models.CharField(max_length=200)
    category = models.ForeignKey(TutorialCategory, default=1, verbose_name="Kategori", on_delete=models.SET_DEFAULT)
    summary = models.CharField(max_length=200)
    slug = models.CharField(max_length=100)  # Not from tutorial, but this is the tutorial slug

    class Meta:
        verbose_name_plural = "Serier"

    def __str__(self):
        return self.series


class Tutorial(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    published = models.DateTimeField("date published", default=datetime.now())
    series = models.ForeignKey(TutorialSeries, default=1, verbose_name="Serie", on_delete=models.SET_DEFAULT)
    id = models.AutoField(primary_key=True)  # This was originally a slug, but now it's the episode number

    def __str__(self):
        return self.title

# Views.py
def slugs(request, series_slug):
    categories = [c.slug for c in TutorialCategory.objects.all()]
    if series_slug in categories:
        match_series = TutorialSeries.objects.filter(category__slug=series_slug)
        series_urls = {}
        for m in match_series.all():
            part_one = Tutorial.objects.filter(series__series=m.series).earliest("published")
            series_urls[m] = part_one.id
        return render(request, "main/category.html", {"part_ones": series_urls})

    tutorials = [t.slug for t in Tutorial.objects.all()]
    if series_slug in tutorials:
        this_tutorial = Tutorial.objects.get(series_slug=series_slug)
        return render(request, "main/tutorial.html", {"tutorial": this_tutorial})

我最初遇到的问题是出现的所有tutorials,而不仅仅是series中的问题。仅显示series可以正常工作。 但是现在,在尝试解决此问题之后,我真的不知道该怎么办。我已经对views.py进行了很多更改,但是现在是原始版本(来自sendtex),并且将教程段更改为ID,并为教程系列添加了一个段。

如何让views.py仅在特定的tutorials中显示series,等等。并在网址中有多个标签?

1 个答案:

答案 0 :(得分:1)

首先,您应该为每个网址格式创建一个专用视图:

# urls.py
urlpatterns = [
    ...
    path("<slug:category_slug>/", views.category_blocks, name="category_blocks"),  # Views all the series in that category
    path("<slug:category_slug>/<slug:series_slug>/", views.series_blocks, name="series_blocks"),  # View all tutorials in series
    path("<slug:category_slug>/<slug:series_slug>/<int:tutorial_id>/", views.episode_blocks, name="episode_blocks"),  # View spesific tutorial nr.
]

# views.py
def category_blocks(request, category_slug):
    # logic to display all tutorial with category is `category_slug`

def series_blocks(requests, category_slug, series_slug):
    # logic to display all tutorial with category is `category_slug` and series is `series_slug` 

def tutorial_blocks(requests, category_slug, series_slug, tutorial_id):
    # logic to display all tutorial with category is `category_slug`, series is `series_slug` and tutorial is `tutorial_id`

逻辑类似于您已经编写的代码。不要忘记检查tutorial.series.slug是否与series_slugseries.category是否与category_slug匹配