Good evening, Django is completely new for me and it's my first question here. I'm trying to create a Webapp. I'm using Django, Python and MariaDB. I created a project with two apps and I have a model for each app. In the fist one I used "slug" as field name and everything is working fine. In the second one I wanted to differentiate that field giving a different name (bk_slug) defined as SlugField. I tried to use the same kind of instructions lines and modifying them for the field name it seems not working. I cannot have the right URL (Class based ListView) and cannot access to the Class based DetailView.... Thanks in advance for your support.
models.py
from django.db import models
from django.conf import settings
from django.utils import timezone
from django.urls import reverse
# book masterdata
class Book(models.Model):
bk_title = models.CharField("Book Title", max_length=100,
primary_key=True)
bk_originaltitle = models.CharField("Book original Title",
max_length=100, blank=True)
bk_author = models.CharField("Author", max_length=50)
bk_editor = models.CharField("Editor", max_length=50)
bk_editiondate = models.CharField("Book Edition date",
max_length=30)
bk_recblocked = models.BooleanField("Book record blocked")
bk_creator = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.PROTECT,
related_name='+', verbose_name="Created by")
bk_creationdate = models.DateTimeField("Creation date",
auto_now=True)
bk_modifier = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.PROTECT,
related_name='+', verbose_name="Last modification by")
bk_modified = models.DateTimeField("Last modification date",
auto_now=True)
bk_slug = models.SlugField(max_length=100, allow_unicode=True,
blank=True)
def __str__(self):
return self.bk_title
def get_absolute_url(self):
return reverse('book_detail', kwargs={'slug': self.bk_slug})
urls.py
from django.urls import path
from dimlibrary.views import BookListView
from dimlibrary.views import BookDetailView
urlpatterns = [
path('', BookListView.as_view(), name='book_list'),
path('<slug:bk_slug>/', BookDetailView.as_view(),
name='book_detail'),
]
views.py
from django.shortcuts import render
# Create your views here.
from django.shortcuts import render
from django.utils import timezone
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView
from dimlibrary.models import Book
# book views :
# List view
class BookListView(ListView):
model = Book
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return context
# Details View
class BookDetailView(DetailView):
model = Book
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return context
```html
{% extends 'base/base.html' %}
{% load static %}
{% block content %}
<h1>Books List</h1>
<ul>
{% for book in object_list %}
<li><a href="{{ dimlibrary.book.get_absolute_url }}">{{
book.bk_title }}</a> - {{ book.bk_author }} -
{{ book.bk_editor }}</li>
{% empty %}
<li>No book registred yet.</li>
{% endfor %}
</ul>
{% endblock content %}
In your DetailView
, you need to specify the slug_field
[Django-doc] as 'bk_slug'
:
class BookDetailView(DetailView):
model = Book
slug_field = 'bk_slug'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return context
In the model, you will need to slugify(…)
[Django-doc] the name, so:
from django.utils.text import slugify
class Book(models.Model):
# …
def save(self, *args, **kwargs):
if not self.bk_slug:
self.bk_slug = slugify(self.title)
return super().save(*args, **kwargs)