Учитывая следующую ситуацию:
# models.py
class Book(Model):
pass
# views.py
class BookDetail(DetailView):
model = Book
# books/urls.py
urlpatterns += [path('detail/<int:pk>', BookDetail.as_view(), 'book_detail')]
# page/urls.py
urlpatterns += [path('books/', include('books.urls'))]
Я могу загрузить подробное представление для объекта с закрытым ключом id 42 в /books/detail/42/
. Если я нахожусь в другом запросе с совершенно другим путем и держу ссылку на объект с идентификатором закрытого ключа 42, существует ли «официальный» или встроенный способ создания URL-адреса /books/detail/42/
? Желательно вне шаблонов, чтобы я мог ответить в формате JSON.
Или идиоматический способ параметризовать элементы пути (books
и detail
) и просто перестроить его самостоятельно?
да, вы можете использовать get_absolute_url
для представлений, специфичных для модели, и тег шаблона {% url ... %}
для вычисления имени представления.
Если у Model
есть представление специфический для отображения деталей, вы можете реализовать get_absolute_url
[Джанго-док] в своей модели, например:
from django.urls import reverse
class Book(Model):
def get_absolute_url(self):
return reverse('book_detail', kwargs = {'pk': self.pk})
Здесь мы используем reverse
[Джанго-док] для «вычисления» URL-адреса для данного имени представления (указанного в вашем path(..., name='book_detail')
) с параметром pk
, pk
из self
.
В своем шаблоне вы можете написать:
<a href = "{{ my_object.get_absolute_url }}">{{ my_object }}</a>
с my_object
именем переменной в вашем шаблоне.
Обратите внимание, что функция redirect
[Джанго-док] понимает get_absolute_url
, и поэтому вы можете написать return redirect(my_object)
в представлении, и оно автоматически вызовет get_absolute_url
для перенаправления на нужное представление.
Если вы сериализуете модель с помощью Django REST framework, вы также можете повторно использовать get_absolute_url
, используя, например, URLField
[drf-doc]:
from rest_framework.serializers import ModelSerializer, URLField class BookSerializer(serializers.ModelSerializer): absolute_url = serializers.URLField( read_only=True, source='get_absolute_url' )
Этот конкретный вариант использования задокументирован в документации по инфраструктуре Django REST.
{% url ...%}
в шаблонеВы также можете рассчитать URL-адрес представления, используя функцию Тег шаблона {% url ... %}
[Django-doc]. Например, вы можете написать:
<a href = "{% url 'book_detail' pk=my_object.pk %}">{{ my_object }}</a>
для вычисления URL-адреса, как мы сделали с get_absolute_url
. Однако это полезно и для других представлений, не связанных с моделью.
Вы должны использовать Джанго Рест Фреймворк
Все встроено, нужно только настроить.