Django переход на страницу по primary key
Вообщем у меня есть страница с марками машин и мне нужно чтобы при клике на определенную марку меня перекидывало на страницу со всеми машинами этой марки. Все данные я в таблицы внес, почему-то на этапе перехода на страницу никак не могу правильно написать:
class Marks(models.Model): // models
mark = models.CharField(max_length=64)
def __str__(self):
return self.mark
class Cars(models.Model):
CarName = models.CharField(max_length=64)
mark = models.ForeignKey(Marks, on_delete=models.CASCADE)
def __str__(self):
return self.CarName
def marks_list(request): // views
marks = Marks.objects.all()
return render(request, 'cars.html', {'marks':marks})
def specific_car(request, pk):
Car = Cars.objects.get(id=pk)
return render(request, 'car_detail.html', {'cars': Car})
urlpatterns = [
path('marks/', marks_list), // urls
path('admin/', admin.site.urls),
path('marks/<pk>', specific_car)
]
{% for mark in marks %} // cars.html
<div>
<a href="{{mark.cars}}">
{{mark.mark}}</a>
</div>
{% endfor %}
В файле car_detail.html у меня выводяться названия машин той или иной марки. Как мне правильно посылаться с файла cars.html чтобы открывать названия машин той или иной марки. Проект Называется cars и одно приложение которое там есть это car_marks
Пойдём по порядку:
Создаем прокет
Думаю, тут сложностей не будет:
pip install django
django-admin startapp CarShop .
python manage.py startapp mainapp
Добавляем приложение в список:
CarShop/settings.py
INSTALLED_APPS = [
...
'mainapp'
]
Создаём модели
mainapp/models.py
from django.db import models
class Mark(models.Model): # Название моделей принято писать в единственном числе
name = models.CharField(max_length=64) # У марки должно быть имя (name), а не mark
class Car(models.Model):
# Для того, чтобы удобно обращаться к машинам марки (например mark.cars.all) нужно указать related_name
mark = models.ForeignKey(Mark, on_delete=models.Case, related_name='cars')
name = models.CharField(max_length=64)
Проводим миграции:
python manage.py makemigrations
python manage.py migrate
Заполняем базу данными. Для этого можно воспользоваться специальной консольной оболочкой django:
python manage.py shell
>>> from mainapp.models import Mark, Car
>>>
>>>
>>> Mark(name='mark1').save()
>>> Mark(name='mark2').save()
>>> Mark(name='mark3').save()
>>>
>>>
>>> Car(mark_id=1, name='car1').save()
>>> Car(mark_id=1, name='car2').save()
>>> Car(mark_id=2, name='car3').save()
>>> Car(mark_id=2, name='car4').save()
>>> Car(mark_id=3, name='car5').save()
>>> Car(mark_id=3, name='car6').save()
Создаём urls
Создаём mainapp/urls.py
mainapp/urls.py
from django.urls import path
from mainapp import views as mainapp
app_name = 'mainapp'
urlpatterns = [
path('marks/', mainapp.marks_list, name='mark_list'), # создаём ссылку на список марок
path('marks/mark/<int:mark_id>/', mainapp.mark_detail, name='mark_detail') # создаём ссылку на просмотр конкретной марки
]
Подключаем его в корневом диспетчере url:
CarShop/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('mainapp.urls', namespace='main')) # Для удобства создаём namespace для приложения
]
Создаём views
mainapp/views.py
from django.shortcuts import render
from mainapp.models import Mark
def marks_list(request):
return render(request, 'mainapp/marks.html', {'marks': Mark.objects.all()})
def mark_detail(request, mark_id: int):
return render(request, 'mainapp/mark_detail.html', {'mark': Mark.objects.get(id=mark_id)}) # Получаем объект марки по id и передаем в шаблон
Создаём шаблоны
Наши шаблоны должны храниться по такому пути: mainapp/templates/mainapp/
:
Создаём mainapp/templates/mainapp/marks.html
. В нём будет список всех марок
mainapp/templates/mainapp/marks.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Марки</title>
</head>
<body>
{% for mark in marks %}
<!-- Применяем url и передаём ей имя ссылки (main - namespace ; mark_detail - name) и id марки -->
<!-- CarShop/urls.py -->
<!-- path('', include('mainapp.urls', namespace='main')) -->
<!-- mainapp/urls.py -->
<!-- path('marks/mark/<int:mark_id>/', mainapp.mark_detail, name='mark_detail') -->
<a href="{% url 'main:mark_detail' mark_id=mark.pk %}">{{ mark.name.capitalize }}</a>
<!-- mark_id в будущем передастся в view -->
<!-- mainapp/views.py -->
<!-- def mark_detail(request, mark_id: int): -->
{% endfor %}
</body>
</html>
Создаём mainapp/templates/mainapp/mark_detail.html
. В нём будет описание и список машин марки
mainapp/templates/mainapp/mark_detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ mark.name }}</title>
</head>
<body>
<p>Машины:</p>
<ul>
{% for car in mark.cars.all %} <!-- Берём все машины марки и выводим -->
<li>{{ car.name }}</li>
{% endfor %}
</ul>
<a href="{% url 'main:mark_list' %}">Назад к списку марок</a> <!-- По аналогии с marts.html передаём namespace и name ссылки -->
</body>
</html>
Итоговая структура
Запускаем сервер
python manage.py runserver 0.0.0.0:8000