@ddgryaz

Как правильно сделать параметризованные запросы в Django?

Доброго времени суток! Подскажите пожалуйста как реализовать вывод дочерней модели, при выборе родительской?
Я уже это делал, во время изучения книги Дронова 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']



Фото для примера:

5fc12c3979874932854975.png
5fc12c41ea24d933251173.png


Я пробую сделать так:
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 %}
  • Вопрос задан
  • 170 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы