Не работает составной url
Django не находит путь, который я указал. Путь вида /title/number. Сколько не гуглил, решения не нашел. В ошибке по пути /title/number "Field 'number' expected a number but got 'dd'." В ошибке ниже в kwargs получены же нужные значения, почему тогда url принял dd, а не "1"?
callback
<function ChapterDetail at 0x000001ECD1EC9F78> callback_args
() callback_kwargs {'number': '1', 'slug': 'dd'} middleware_method
<bound method CsrfViewMiddleware.process_view of <django.middleware.csrf.CsrfViewMiddleware object at 0x000001ECD2074D88>> request <WSGIRequest: GET '/dd/1/'> response
None self
<django.core.handlers.wsgi.WSGIHandler object at 0x000001ECD17BE7C8> wrapped_callback
<function ChapterDetail at 0x000001ECD1EC9F78>
Как дать понять django, что я хочу путь /title/number ?
models.py
class MangaTitle(models.Model):
STATUS_COMPLETED = "completed"
STATUS_IN_PROGRESS = "in_progress"
STATUS_TRANSLATE = (
(STATUS_IN_PROGRESS, "Продолжается"),
(STATUS_COMPLETED, "Завершен")
)
STATUS_TITLE = (
(STATUS_IN_PROGRESS, "Продолжается"),
(STATUS_COMPLETED, "Завершен")
)
name = models.CharField(max_length=255, verbose_name="Название тайтла")
second_name = models.CharField(max_length=255, verbose_name="Альтернативное название")
status_translate = models.CharField(max_length=100, verbose_name="Статус перевода", choices=STATUS_TRANSLATE,
default=STATUS_IN_PROGRESS)
status_title = models.CharField(max_length=100, verbose_name="Статус тайтла", choices=STATUS_TITLE,
default=STATUS_IN_PROGRESS)
total_views = models.PositiveIntegerField(verbose_name="Число просмотров", default=0)
total_chapter = models.PositiveIntegerField(verbose_name="Число глав", default=0)
date_of_release = models.DateTimeField(verbose_name="Дата выпуска", default=timezone.now)
genre = models.ForeignKey(MangaGenre, verbose_name="Жанр", on_delete=models.CASCADE)
slug = models.SlugField(unique=True, blank=True, null=True)
descriptions = models.TextField(verbose_name="Описание тайтла", blank=True, null=True)
img = models.ImageField(verbose_name="Изображение", upload_to="cover/")
author_title = models.ForeignKey(Author, verbose_name="Автор", on_delete=models.CASCADE)
artist_title = models.ForeignKey(Artist, verbose_name="Художник",
on_delete=models.CASCADE,
default=author_title.name)
category = models.ForeignKey(Category, verbose_name="Категория", on_delete=models.CASCADE, null=True, blank=True)
def save(self, *args, **kwargs):
self.slug = translit_slug(self.name)
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse("book_detail", kwargs={"slug":self.slug})
# def get_absolute_url(self):
# get_manga_url(self, "product_detail")
def __str__(self):
return self.name
class Chapter(models.Model):
title = models.ForeignKey(MangaTitle, verbose_name="Тайтл", on_delete=models.CASCADE)
name = models.TextField(verbose_name="Название главы", blank=True, null=True)
number = models.PositiveIntegerField(verbose_name="Номер главы")
# id = models.AutoField(primary_key=True)
slug = models.SlugField(verbose_name="Ссылка на главу", null=True, blank=True)
chapter_zip = models.FileField(verbose_name="Архив главы", blank=True, null=True, upload_to="zipChapter/")
class Meta:
unique_together = [["title", "slug"]]
def __str__(self):
return f"{self.title} - {self.number} - {self.name}"
def save(self, *args, **kwargs):
self.slug = self.number
if self.chapter_zip:
# extract_zip_to_model(self.chapter_zip, self.title, self.number)
test(self.chapter_zip, self.title, self.number)
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse("chapter_detail", kwargs={"number": self.slug})
urls.py
from django.contrib import admin
from django.urls import path, include, re_path
from .views import Base, ChapterRead, ChapterDetail
extra_patterns = [
#path("<str:url>/", ChapterRead.as_view(), name="chapter-read"),
path("", ChapterDetail.as_view(), name="chapter_detail"),
]
urlpatterns = [
path("", Base.as_view(),name="book_list"),
path("<str:slug>/", ChapterRead.as_view(), name="book_detail"),
path("<str:slug>/<str:number>/", include(extra_patterns))
#path("<str:slug>/<int:number>/", ChapterDetail.as_view(), name="chapter_detail")
]
views.py
from django.shortcuts import render, get_object_or_404
from django.views.generic import DetailView, View
from .models import *
# Create your views here.
class Base(View):
def get(self, request, *args, **kwargs):
manga = MangaTitle.objects.all()
return render(request, "base.html", context={"manga": manga})
class ChapterRead(DetailView):
model = MangaTitle
context_object_name = "manga"
template_name = "chapter.html"
slug_field = "slug"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["chapter"] = Chapter.objects.filter(title=self.object)
return context
class ChapterDetail(DetailView):
model = Chapter
context_object_name = "chapter"
template_name = "chapter_read.html"
slug_field = "number"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["imgs"] = ImgChapter.objects.filter(chapter=self.object)
return context
chapter.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{ manga.name }}
{% for i in chapter %}
<a href="{% url "chapter_detail" i.title.slug i.slug %}">{{ i.slug }}</a>
{% endfor %}
</body>
</html>