I am trying to pass two parameters from template (“zn” and “ru”) to filter posts in view. It seems to me, that the variables of both parameters are OK, but not under proper name. The view probably doesn’t recognize which is which. Filtering with parameter “zn” works, but filtering with parameter “ru” doesn’t (see the error statement in picture). enter image description here
urls.py:
from django.urls import path
from . import views
urlpatterns = [
...
path("clanky/", views.clanek_vyber, name="clanky_vyber", kwargs={'zn': '', 'ru': ''}),
path("clanky/<slug:zn>/", views.clanek_vyber, name="clanky_vyber", kwargs={'ru': ''}),
path("clanky/<slug:ru>/", views.clanek_vyber, name="clanky_vyber", kwargs={'zn': ''}),
path("clanky/<slug:zn>/<slug:ru>/", views.clanek_vyber, name="clanky_vyber"),
views.py:
from django.shortcuts import render
from django.utils import timezone
from django.views import generic
from django.core.paginator import Paginator
...
from .models import Clanek, Rubrika, Znacka, GalerieObrazku, Hlavni_banner
...
def clanek_vyber(request, zn, ru):
bannery_1 = Hlavni_banner.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')[:1]
clanek_znacka = Clanek.objects.values('znacka')
znac = Znacka.objects.filter(id__in=clanek_znacka)
rubr = Clanek.objects.distinct('rubrika').order_by('rubrika_id')
if (zn!="" and ru!=""):
uvodni_clanek = Clanek.objects.filter(znacka__slug=zn).filter(rubrika__slug=ru).order_by('-published_date')[:1]
zna = Znacka.objects.get(slug=zn)
rub = Rubrika.objects.get(slug=ru)
cla_vyb = Clanek.objects.filter(znacka__slug=zn).filter(rubrika__slug=ru).order_by('-published_date')[1:]
paginator = Paginator(cla_vyb, 20) # ukáže dvacet dalších článků
page_number = request.GET.get("page")
page_obj = paginator.get_page(page_number)
context = {
'bannery_1': bannery_1,
'uvodni_clanek': uvodni_clanek,
'page_obj': page_obj,
'znac': znac,
'zna': zna,
'zn': zn,
'rubr': rubr,
'rub': rub,
'ru': ru
}
return render(request, "zentour/clanky.html", context)
if(zn!=""):
uvodni_clanek = Clanek.objects.filter(znacka__slug=zn).order_by('-published_date')[:1]
zna = Znacka.objects.get(slug=zn)
cla_vyb = Clanek.objects.filter(znacka__slug=zn).order_by('-published_date')[1:]
paginator = Paginator(cla_vyb, 20) # ukáže dvacet dalších článků
page_number = request.GET.get("page")
page_obj = paginator.get_page(page_number)
context = {
'bannery_1': bannery_1,
'uvodni_clanek': uvodni_clanek,
'page_obj': page_obj,
'znac': znac,
'zna': zna,
'zn': zn,
'rubr': rubr
}
return render(request, "zentour/clanky.html", context)
elif(ru!=""):
uvodni_clanek = Clanek.objects.filter(rubrika__slug=ru).order_by('-published_date')[:1]
rub = Rubrika.objects.get(slug=ru)
cla_vyb = Clanek.objects.filter(rubrika__slug=ru).order_by('-published_date')[1:]
paginator = Paginator(cla_vyb, 20) # ukáže dvacet dalších článků
page_number = request.GET.get("page")
page_obj = paginator.get_page(page_number)
context = {
'bannery_1': bannery_1,
'uvodni_clanek': uvodni_clanek,
'page_obj': page_obj,
'znac': znac,
'rubr': rubr,
'rub': rub,
'ru': ru
}
return render(request, "zentour/clanky.html", context)
else:
uvodni_clanek = Clanek.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')[:1]
dalsi_clanky = Clanek.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')[1:]
paginator = Paginator(dalsi_clanky, 20) # ukáže dvacet dalších článků
page_number = request.GET.get("page")
page_obj = paginator.get_page(page_number)
context = {
'bannery_1': bannery_1,
'uvodni_clanek': uvodni_clanek,
'page_obj': page_obj,
'znac': znac,
'rubr': rubr
}
return render(request, "zentour/clanky.html", context)
html, single post:
<div class="odkazy_pod_clanky">
<small>
Značka:
{% for z in clanek.znacka.all %}
<a href="{% url 'clanky_vyber' zn=z.slug ru='' %}">{{ z }}, </a>
{% endfor %}
Rubrika: <a href="{% url 'clanky_vyber' zn='' ru=clanek.rubrika.slug %}">{{ clanek.rubrika }}</a>
<!-- Zařazení: {{ clanek.urceni.all|join:", "}} -->
</small> <br>
</div>
html, dropdowns (javascript) at page with list of posts:
<div class="rozbalovaci_znacka">
<button onclick="rozbal_znacka()" class="menu_znacka">značka: {{ zna }}</button>
<div id="rozbalovacka_znacka" class="polozky_k_rozbaleni_znacka">
<a href="{% url 'clanky_vyber' zn="" %}">jakákoliv</a>
{% for za in znac %}
<a href="{% url 'clanky_vyber' zn=za.slug %}">{{ za.nazev_znacky }}</a>
{% endfor %}
</div>
</div>
<!-- třídění dle rubriky-->
<div class="rozbalovaci_rubrika">
<button onclick="rozbal_rubrika()" class="menu_rubrika">rubrika: {{ rub }}</button>
<div id="rozbalovacka_rubrika" class="polozky_k_rozbaleni_rubrika">
<a href="{% url 'clanky_vyber' ru="" %}">jakákoliv</a>
{% for rb in rubr %}
<a href="{% url 'clanky_vyber' ru=rb.rubrika.slug %}">{{ rb.rubrika }}</a>
{% endfor %}
</div>
</div>
I have also tried to filter posts by django-filters and it worked, but I would prefer the solution above. I am stacked in this for long time and I was not able to find a proper solution in existing questions on this site. Thank you, Pavel
The paths overlap completely. Indeed:
path("clanky/<slug:zn>/", views.clanek_vyber, name="clanky_vyber", kwargs={'ru': ''}),
path("clanky/<slug:ru>/", views.clanek_vyber, name="clanky_vyber", kwargs={'zn': ''}),
if the path is clanky/foo
then both paths match. So it will check the paths in the order defined and thus always pick the first one, so with zn
as value, and ru
empty.
You thus should ensure that the paths do not overlap. Probably it is better that these do not overlap completely:
urlpatterns = [
path(
'clanky/zn/<slug:zn>/',
views.clanek_vyber,
name='clanky_vyber',
kwargs={'ru': ''},
),
path(
'clanky/ru/<slug:ru>/',
views.clanek_vyber,
name='clanky_vyber',
kwargs={'zn': ''},
),
path(
'clanky/znru/<slug:zn>/<slug:ru>/',
views.clanek_vyber,
name='clanky_vyber',
),
]