За время создания и разработки фреймворка Python Django было выработано несколько правил наименование. Одно из этих правил касается возможности генерирования ссылок на объекты, которые создаются и меняются в базе данных. Такой правило реализуется через метод с названием get_absolute_url().
Для примера у нас есть класс (модель), которая хранит людей. Для каждого из них мы должны генерировать ссылку для более детального просмотра. Мы можем создать этот метод следующим образом:
from django.db import models
class Person(models.Model):
choices = (
('M', 'Male'),
('F', 'Female')
)
name = models.CharField(max_length=140)
sex = models.CharField(max_length, choices=choices)
age = models.IntegerField()
def get_absolute_url(self):
return f'/person/{self.name}/'
В данном случае мы возвращаем уникальную ссылку каждый раз, когда обращаемся к методу объекта. Например ссылка вернется так:
Person.objects.get(name='Alex').get_absolute_url()
Или с со всеми объектами или с фильтром:
for el in Person.objects.all():
print(el.get_absolute_url())
Как вы знаете, кроме полей созданных вами, всегда так же создаются и идентификатор записи к которым вы можете обратиться используя переменные "self.pk" или "self.id". Так как эти идентификаторы уникальные - они хорошо подходят для ссылок:
def get_absolute_url(self):
return f'/person/{self.pk}/'
Альтернативные метод создания ссылок - это использование метода reverse(), который будет просто подставлять значения в ссылку указанную в файле urls.py:
from django.db import models
from django.shortcuts import reverse
class Person(models.Model):
....
def get_absolute_url(self):
return reverse('myurl', kwargs={'id': self.id, 'name': self.name})
Где первое значение - название(name) в urls.py, а args - словарь содержащий значения для подстановки. Такой метод будет работать со следующим urls.py:
from django.urls import path
app_name = 'my_app'
urlpatterns = [
path('users/<int:id>/<str:name>/', SomView.as_view(), name='myurl')
]
Если у вас множество приложений, то в reverse вы можете указать значение переменной app_name. Это поможет минимизировать ошибки в будущем:
def get_absolute_url(self):
return reverse('my_app:myurl', kwargs={'id': self.id, 'name': self.name})
Этот метод, так же как и любой другой, мы сможем выводить в шаблонах:
{% for el in objects %}
<a href="{{ el.get_absolute_url }}"></a>
{% endfor %}
Само определение такого метода автоматически открывает некоторые возможности. Например в панели администрирования, у этой модели, появится кнопка 'view on site'. Так же этот метод может автоматически использоваться в CreateView если вы не укажите атрибут у success_url.
...