Доброго времени суток! Подскажите пожалуйста как реализовать вывод дочерней модели, при выборе родительской?
Я уже это делал, во время изучения книги Дронова Django 3.0, но сейчас в другом проекте никак не могу сообразить как это реализовать, мозг вскипает :(
У меня есть две модели:
class Handbook(models.Model):
title = models.CharField('Наименование', max_length=250, db_index=True)
short_title = models.CharField('Короткое наименование', max_length=100)
description = models.TextField('Описание')
version = models.CharField('Версия', max_length=250) #unique=True
date = models.DateField('Дата начала действия справочника этой версии')
def __str__(self):
return self.title
class Meta:
verbose_name = 'Справочник'
verbose_name_plural = 'Справочники'
class Element(models.Model):
handbook = models.ForeignKey(Handbook, on_delete=models.PROTECT, verbose_name='Родительский идентификатор', null=True)
code = models.CharField('Код элемента', max_length=250)
value = models.CharField('Значение элемента', max_length=250)
def __str__(self):
return self.value
class Meta:
verbose_name = 'Элемент'
verbose_name_plural = 'Элементы'
Файл view: (то что закомментировано - это мои попытки реализации)
from django.shortcuts import render
from .models import Handbook, Element
def index(request):
list_handbooks = Handbook.objects.all()
return render(request, 'handbook/index.html', {'list_handbooks': list_handbooks})
def elements(request):
list_elements = Element.objects.all()
return render(request, 'handbook/elements.html', {'list_elements': list_elements})
# def by_elements(request, element_id):
# elements = Element.objects.filter(handbook=element_id)
# handbooks = Handbook.objects.all()
# current_handbooks = Handbook.objects.get(pk=element_id)
# context = {
# 'elements': elements,
# 'handbooks': handbooks,
# 'current_handbooks': current_handbooks,
# }
# return render(request, 'by_element.html', context)
def by_elements(request,):
return render(request, 'handbook/by_elements.html',)
Файл URL:
urlpatterns = [
path('', views.index, name='home'),
path('elements', views.elements, name='elements'),
path('by_elements', views.by_elements, name='by_elements'),
]
Собственно мне нужно, чтобы на странице .../by_elements отображались все элементы, и отдельно ссылки на категории(в данном случае справочники), кликнув на которые - откроется страница .../by_elements/1 и будут показаны только элементы по выбранной категории.
Ниже в спойлере я приведу код с другого проекта, где такой функционал уже реализовал когда-то. Сейчас же я не могу понять, как правильно указать в url.py все это дело.
Спойлер
Файл view:
def by_rubric(request, rubric_id):
bbs = Bb.objects.filter(rubric = rubric_id)
rubrics = Rubric.objects.all()
current_rubric = Rubric.objects.get(pk=rubric_id)
context = {'bbs': bbs, 'rubrics': rubrics,
'current_rubric': current_rubric}
return render(request, 'bboard/by_rubric.html', context)
Файл url:
from django.urls import path
from .views import index, by_rubric, BbCreateView
urlpatterns = [
path('add/', BbCreateView.as_view(), name = 'add'),
path('<int:rubric_id>/', by_rubric, name = 'by_rubric'),
path('', index, name = 'index'),
]
Файл models:
from django.db import models
class Bb(models.Model):
title = models.CharField(max_length = 50, verbose_name = 'Товар')
content = models.TextField(null = True, blank = True, verbose_name = 'Описание')
price = models.FloatField(null = True, blank = True, verbose_name = 'Цена')
published = models.DateTimeField(auto_now_add = True, db_index = True, verbose_name = 'Опубликовано')
rubric = models.ForeignKey('Rubric', null = True,
on_delete=models.PROTECT, verbose_name = 'Рубрика')
class Meta:
verbose_name_plural = 'Объявления'
verbose_name = 'Объявление'
ordering = ['-published']
class Rubric(models.Model):
name = models.CharField(max_length = 20, db_index = True, verbose_name = 'Название')
def __str__(self):
return self.name
class Meta:
verbose_name_plural = 'Рубрики'
verbose_name = 'Рубрика'
ordering = ['name']
Я пробую сделать так:
view:
def by_elements(request, element_id):
elements = Element.objects.filter(handbook=element_id)
handbooks = Handbook.objects.all()
current_handbooks = Handbook.objects.get(pk=element_id)
context = {
'elements': elements,
'handbooks': handbooks,
'current_handbooks': current_handbooks,
}
return render(request, 'handbook/by_elements.html', context)
url:
urlpatterns = [
path('', views.index, name='home'),
path('elements', views.elements, name='elements'),
path('<int:element_id>/', views.by_elements, name='by_elements'),
]
При переходе на localhost:8000/by_elements, я получаю 404 not found
UPD:
view:
urlpatterns = [
path('', views.index, name='home'),
path('elements', views.elements, name='elements'),
path('by_elements/<int:element_id>/', views.by_elements, name='by_elements'),
]
Я все так же получаю 404 при открытии localhost:8000/by_elements
Но, если я вбиваю localhost:8000/by_elements/1 - я получаю рабочую страницу, код файла by_elements:
{% extends 'handbook/basic.html' %}
{% block title %}Sort List Elements{% endblock %}
{% block content %}
<div class="features">
<h1>Элементы по справочникам</h1>
<p>Выберите справочник, чтобы отобразились его элементы.</p>
{% for el in elements %}
<p>{{ el.value }}</p>
{% endfor %}
</div>
{% endblock %}