D
D
ddgryaz2020-11-27 19:42:31
Django
ddgryaz, 2020-11-27 19:42:31

How to properly make parameterized queries in Django?

Good day! Please tell me how to implement the output of the child model, when choosing the parent?
I already did this while studying Dronov's Django 3.0 book, but now in another project I can't figure out how to implement it, my brain boils :(

I have two models:

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 file: (what is commented out is my implementation attempts)
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',)


File URL:
urlpatterns = [
    path('', views.index, name='home'),
    path('elements', views.elements, name='elements'),
    path('by_elements', views.by_elements, name='by_elements'),
]


Actually, I need all the elements to be displayed on the .../by_elements page, and separately links to categories (in this case, directories), by clicking on which, the .../by_elements/1 page will open and only elements from the selected category will be shown.

Below in the spoiler, I will give the code from another project, where I have already implemented such functionality once. Now I can't figure out how to correctly specify the whole thing in url.py.

Spoiler

Файл 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']



Photo for example:

5fc12c3979874932854975.png
5fc12c41ea24d933251173.png


I'm trying to do this:
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'),
]


When going to localhost:8000/by_elements, I get 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'),
]

I still get 404 when opening localhost:8000/by_elements
But if I type in localhost:8000/by_elements/1 - I get a working page, by_elements file code:
{% 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 %}

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question