Django django-cms reverse 'NoReverseMatch at..' multisite language - python

This seems to be a "classic" problem :
NoReverseMatch at /tr/showroom/
Reverse for 'project-list' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
But the problem is, when I check the different topic on the internet and then my files, I don't get it.
So it's working perfectly on the native language. It happens when I try to change the language on this showroom page only.
Every page that have been copy with the commad cms copy works fine except this one.
Well, here is the model :
def get_slug(self):
return self.safe_translation_getter(
'slug',
language_code=get_language(),
any_language=False)
def get_absolute_url(self, current_app=None):
"""
Warning: Due to the use of django application instance namespace
(for handle multi instance of an application)we add the possibility
to use it with the reverse.
So if get_absolute_url is call without app instance it may failed (
for example in django_admin)
"""
lang = get_language()
if self.has_translation(lang):
kwargs = {'slug': self.get_slug()}
return reverse('djangocms_showroom:project-detail',
kwargs=kwargs,
current_app=current_app)
return reverse('djangocms_showroom:project-list', current_app=current_app)
def get_full_url(self, site_id=None):
return self._make_full_url(self.get_absolute_url(), site_id)
def _make_full_url(self, url, site_id=None):
if site_id is None:
site = Site.objects.get_current()
else:
site = Site.objects.get(pk=site_id)
return get_full_url(url, site)
The url :
from django.conf.urls import patterns, url
from .views import (ProjectListView, ProjectDetailView)
urlpatterns = patterns(
'',
url(r'^$', ProjectListView.as_view(), name='project-list'),
url(r'^project/(?P<slug>\w[-\w]*)/$', ProjectDetailView.as_view(), name='project-detail'),
)
And the html error :
Error during template rendering
In template /var/www/webapps/blippar_website/app/blippar/templates/djangocms_showroom/project_list.html, error at line 14
Which is :
<form id="projects-filter" action="{% url 'djangocms_showroom:project-list' %}">
Well, I am not very good yet with django and django-cms, if someone has any clue, it would be marvellous !

Related

Django list view repeatedly fails, but detail pages work

testt1
is my view for taking a queryset and turning out a list of objects and their foreign key children.
mydetail
is the detail view for the individual objects. No slug is used in the list, but it is in the list template to call the detail pages. But all these errors come from trying to call the list, not the detail. If I just type the slug into the address bar, all my detail pages come up just fine!
I have tried a lot of different things, and get a lot of different errors, but the bottom line is always the same: no list
named url fails
Error during template rendering
In template /home/malikarumi/Projects/hattie/templates/base.html, error at line 44
Reverse for 'jhp_url' not found. 'jhp_url' is not a valid view function or pattern
name.
‘jhp_url’ is the named url for the detail page.
But here is line 44:
<link href="{% static 'plugins/owl-carousel/owl.carousel.css' %}" rel="stylesheet">
the urlpattern:
path('<slug:slug>/', mydetail, name='jhp_url'),
the call to reverse():
def get_absolute_url(self):
return reverse(‘jhp_url', kwargs={'slug': self.slug})
namespaced url fails
Error during template rendering
In template /home/malikarumi/Projects/hattie/templates/base.html, error at line 44
Reverse for 'jhp_url' with keyword arguments '{'slug': ''}' not found. 1 pattern(s) tried: ['(?P[^/]+)/courts/(?P[-a-zA-Z0-9_]+)/$']
Now it has an empty string for the slug. The pattern is right. If it had a slug, it would work.
def get_absolute_url(self):
return reverse('bench:jhp_url', kwargs={'slug': self.slug})
list template:
<h3>{{ C.name }}</h3>
urlpattern is the same.
no slug passed
testt1() missing 1 required positional argument: 'slug'
Which means that as I have currently defined it:
def testt1(request, slug, *args, **kwargs):
print(request.slug)
Is not being provided the slug variable / value. Now it might also be a question of position, so I changed only this:
def testt1(request, *args, **kwargs):
But since slug is still in the return value, now I get:
Unresolved reference 'slug'
I take it out, and the autoreloader wakes up…
'WSGIRequest' object has no attribute 'slug'
Yes, well, that's what I suspected. That’s why I had the print in there. The question is: why does it not have slug?
https://docs.djangoproject.com/en/3.2/topics/http/urls/#including-other-urlconfs
Whenever Django encounters include(), it chops off whatever part of the URL matched up to that point and sends the remaining string to the included URLconf for further processing.
Apparently, I don’t understand this process, because I always assumed this meant the slug part of my url was being passed along as part of the request object. But now I see that the word 'slug' does not appear in the docs on the response request page:
https://docs.djangoproject.com/en/dev/ref/request-response/
extra arguments fail
The docs also give the option of passing ‘extra arguments’:
https://docs.djangoproject.com/en/3.2/topics/http/urls/#passing-extra-options-to-include
https://docs.djangoproject.com/en/3.2/topics/http/urls/#passing-extra-options-to-view-functions
But this says nothing about using extra arguments in conjunction with named or even namespaced urls. Does that mean they don't, or can't go together? Then shouldn’t they say so explicitly, like the Zen of Python? Anyway, my efforts in this area all failed miserably:
File "/home/malikarumi/Projects/hattie/bench/urls.py", line 13
path('<slug:slug>', mydetail, name='jhp_url', {'slug': slug}),
^
SyntaxError: positional argument follows keyword argument
Are they saying a dictionary is a positional argument, and not a keyword?
File "/home/malikarumi/Projects/hattie/bench/urls.py", line 14, in <module>
path('', testt1, slug='slug', name='testt1'),
TypeError: _path() got an unexpected keyword argument 'slug'
File "/home/malikarumi/Projects/hattie/bench/urls.py", line 13, in <module>
path('<slug:slug>', mydetail, slug='slug', name='jhp_url'),
TypeError: _path() got an unexpected keyword argument 'slug'
File "/home/malikarumi/Projects/hattie/bench/urls.py", line 13, in <module>
path('<slug:slug>', mydetail, name='jhp_url', slug=slug),
NameError: name 'slug' is not defined
It's not? then wtf is 'slug:slug'???
Clearly, the slug is not being passed. If it isn't happening automatically,
and it isn't part of the request object - despite slug:slug in the
urlpattern, and I can't use these extra arguments, how am I supposed to get
the slug passed?!
explicit slug keyword argument in view fails:
File "/home/malikarumi/Projects/hattie/bench/views.py", line 22
def testt1(request, *args, '<slug:slug>', **kwargs):
^
SyntaxError: invalid syntax
Just in case you wondering, yes, I did try explicitly passing the slug as a keyword. All such efforts failed.
def testt1(request, slug=slug, **kwargs):
unresolved reference slug
def testt1(request, slug=self.slug, **kwargs):
unresolved reference self
UPDATE
As requested, here is my latest version of views and urls, and at the bottom a link to the full stacktrace going back to yesterday.
VIEWS
from django.shortcuts import render
from bench.models import Jurisdiction
from django.shortcuts import get_object_or_404
from statedict import sdl
j = Jurisdiction.objects.all()
from urllib.parse import urlparse
def mydetail(request, slug, **kwargs):
court = j.get(slug=slug)
# twodigit = twodigit
return render(request, 'bench/jhp_.html',
{'court': court})
def testt1(request, **kwargs):
federalcourts = j.filter(sphere="Appeals").filter(purview="Federal")
circuits = federalcourts.order_by('siblingrank')
scotus = circuits.first().name
context = {'circuits': circuits, 'scotus': scotus, 'slug': slug}
return render(request, 'bench/listtest1.html', context)
URLS
from django.urls import path
from bench.views import mydetail, testt1
app_name = 'bench'
urlpatterns = [
path('/', mydetail, name='jhp_url'),
path('', testt1, name='testt1'),
]
STACKTRACE:
https://docs.google.com/document/d/1ktm-y_AEUrllw0kSctlLgUyNfxVx6eFnYlOZCs-jM2w/edit?usp=sharing
thank you
I would drop the **kwargs from your views unless you have a good reason not to. The reason is that it will hide problems with your views and urls.
The way I would write your views and urls are as follows:
# views.py
def mydetail(request, slug):
...
def testt1(request):
...
# urls.py
app_name = 'bench'
urlpatterns = [
path('<slug:slug>/', mydetail, name='jhp_url'),
path('/', testt1, name='testt1'),
]
The fully qualified url names for these would be:
bench:jhp_url
bench:testt1
If you're using something like:
<h3>{{ C.name }}</h3>
And it's still giving you an error about Reverse for 'jhp_url' with keyword arguments '{'slug': ''}' not found., then the issue is that C.slug is resolving to an empty string or None, or C is None.

Django: passing a URL parameter to every instance of a reverse URL lookup in a template tag

Sorry if the title is unclear, I'm not sure the best way to describe the issue. I have an application with a Ticket model and a Team model. All Tickets are associated with a single Team. The issue I'm having is a problem of URL reversing. I'm trying to set it up my URLs like so: /<team_pk>/tickets/ displays a list of tickets associated with the Team specified by team_pk. So /1/tickets/ would display all of the tickets for the first Team. Both of these objects are in the app tracker.
To do this, I've set up my project/urls.py files like so:
project/urls.py
urlpatterns = [ path('<team_pk>/', include('tracker.urls', namespace='tracker')), ]
tracker/urls.py
urlpatterns = [ path('tickets/', views.TicketTable.as_view(), name='ticket_list'), ]
Then, inside my html templates, I have the following URL tag:
href="{% url 'tracker:ticket_list' %}"
This results in a NoReverseMatch error:
NoReverseMatch at /1/tickets/
Reverse for 'ticket_list' with no arguments not found. 1 pattern(s) tried: ['(?P<team_pk>[^/]+)/tickets/$']
What I would like is for the reverse match to just use the current value for the team_pk URL kwarg.
What I have tried to fix it:
I have found the following solution to the problem, but it involves a lot of repetition, and I feel like there must be a DRYer way.
First, I extend the get_context_data() method for every view on the site.
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['current_team_pk'] = self.kwargs['team_pk']
return context
Then I reference this context in every URL template tag:
href="{% url 'tracker:ticket_list' team_pk=current_team_pk %}"
This results in the desired behavior, but it's a lot of repetition. So, is there a better way?
Edit:
Based on Willem Van Onsem's suggestion, I changed the URL template tag to href="{% url 'tracker:ticket_list' team_pk=team_pk %}", referencing the URL kwarg directly. But this doesn't seem to be working reliably. On the index page /<team_pk>/ loads just fine, and it includes two relevant URLs: /<team_pk>/ and /<team_pk>/tickets/. When I navigate to /<team_pk>/tickets/, however, I get another NoReverseMatch error:
NoReverseMatch at /1/tickets/
Reverse for 'home' with keyword arguments '{'team_pk': ''}' not found. 1 pattern(s) tried: ['(?P<team_pk>[^/]+)/$']
It seems the URL kwarg <team_pk> is not being passed for some reason. But the only link to 'home' is part of my base.html, which the other templates are extending. So the relevant template tags are the same.
Edit 2:
The view in question:
class TicketTable(LoginRequiredMixin, SingleTableMixin, FilterView):
table_class = my_tables.TicketTable
template_name = 'tracker/ticket_list.html'
filterset_class = TicketFilter
context_object_name = 'page'
table_pagination = {"per_page": 10}
PAGE_TITLE = 'Open Tickets'
TICKET_STATUS_TOGGLE = 'Show Closed Tickets'
TICKET_STATUS_TOGGLE_URL = 'tracker:closed_ticket_list'
DISPLAY_DEV_FILTER = True
DISPLAY_STATUS_FILTER = True
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['page_title'] = self.PAGE_TITLE
context['ticket_status_toggle'] = self.TICKET_STATUS_TOGGLE
context['ticket_status_toggle_url'] = self.TICKET_STATUS_TOGGLE_URL
context['display_dev_filter'] = self.DISPLAY_DEV_FILTER
context['display_status_filter'] = self.DISPLAY_STATUS_FILTER
return context
def get_queryset(self):
return models.Ticket.objects.filter_for_team(self.kwargs['team_pk']).filter_for_user(self.request.user).exclude(status='closed')
Edit 3:
I found a solution to access the URL kwargs without modifying context data. I'm not sure why team_pk=team_pk didn't work in the URL tag, but team_pk=view.kwargs.team_pk does work.
Based on the comments and responses from Willem Van Onsem, a friend of mine, and some of my own digging, I found what I think is the DRYest way to do what I was trying to do. I created a custom mixin:
class CommonTemplateContextMixin:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.kwargs.get('team_pk'):
context.setdefault('team_pk', self.kwargs.get('team_pk'))
else:
context.setdefault('team_pk', self.request.user.teams.all()[0].pk)
return context
Then I subclass this mixin with all my views. Then I have a team_pk template tag inside all my templates, and I just add team_pk=team_pk to all my URL template tags. The only advantage to using this instead of team_pk=view.kwargs.team_pk is that I can add some additional logic for the case when the URL kwarg isn't available.

Reverse URL in Django 2.0

The new Django 2.0 update broke my way of reversing url and printing it to the template. Using regular expression, it would work fine but when using the new simplified way, it returns an error.
NoReverseMatch at /blog/archive/
Reverse for 'article' with keyword arguments '{'id': 1}' not found. 1 pattern(s) tried: ['blog/article/<int:id>/$']
Here is what I use to print the url,
<h3 class="item-title">{{ article.title }}</h3>
Here is the url pattern,
url(r'^blog/article/<int:id>/$', views.article, name='article'),
and here is the article function,
def article(request, id):
try:
article = Article.objects.get(id=id)
except ObjectDoesNotExist:
article = None
context = {
'article': article,
'error': None,
}
if not article:
context['error'] = 'Oops! It seems that the article you requested does not exist!'
return render(request, 'blog/article.html', context)
I haven't found a solution to this yet. Hopefully this post will help others.
In Django 2.0, url() is an alias for re_path() and still uses regular expressions.
Use path() for the simplified syntax.
from django.urls import path
urlpatterns = [
path(r'^blog/article/<int:id>/$', views.article, name='article'),
]

NoReverseMatch for the new object

Use Django 1.10.4. I have a model Stream, for which I created CreateView. When objects are created through the admin panel everything works fine, but when I use the form CreateView, an object is created (either in admin or in the database is no different from the other), but attempts to provide a link to it through DetailView result in an error:
NoReverseMatch at /
Reverse for 'detail_stream' with arguments '()' and keyword arguments '{'pk': 17}' not found.
2 pattern(s) tried: ['(?P<pk>[0-9])/$', 'streams/(?P<pk>[0-9])/$']
This error occurs when displaying the ListView, and then only for an object created through CreateView.
The place where the error occurs:
{% for item in stream_list %}
<a href="/streams{% url "detail_stream" pk=item.id %}">
...
</a>
{% endfor %}
When you try to go directly to DetailView (http://127.0.0.1:8000/streams/17) 404 error.
urls.py:
from django.conf.urls import url
from .views import StreamDetail, StreamUpdate
urlpatterns = [
url(r'^$', StreamList.as_view(), name='streams'),
url(r'^(?P<pk>[0-9])/$', StreamDetail.as_view(), name='detail_stream'),
url(r'^(?P<pk>[0-9])/update/$', StreamUpdate.as_view()),
]
Also, the url for the streams added to the main site urlpatterns.
View:
class StreamCreate(LoginRequiredMixin, CreateView):
login_url = '/login/'
def form_valid(self, form):
regex = re.compile('[^a-zA-Z]')
newtags = []
for tag in form.cleaned_data['tags']:
tag = regex.sub('',tag)
newtags.append(tag)
form.cleaned_data['tags'] = newtags
return super(StreamCreate,self).form_valid(form)
def form_invalid(self, form):
print(form.errors)
return super(StreamCreate,self).form_invalid(form)
def get_success_url(self):
return reverse('streams')
I suspect that something I did not realize at CreateView, but I can not understand that and need your help.
Your regex in the given route is wrong.
url(r'^(?P<pk>[0-9])/$', StreamDetail.as_view(), name='detail_stream')
[0-9] means it expects a single-digit number. 17 has two digits, so the regexp needs to take that into account (add + there)
url(r'^(?P<pk>[0-9]+)/$', StreamDetail.as_view(), name='detail_stream')
Some other routes in there have the same issue.

Django CMS 2.1.0 App Extension NoReverseMatch TemplateSyntaxError

I'm writing a custom app for Django CMS, but get the following error when trying to view a published entry in the admin:
TemplateSyntaxError at /admin/cmsplugin_publisher/entry/
Caught NoReverseMatch while rendering: Reverse for 'cmsplugin_publisher_entry_detail' with arguments '()' and keyword arguments '{'slug': u'test-german'}' not found.
I can get the app working if I give the app a URL in my main application urls.py, but that fixes the app to a required URL, I just want extend Django CMS so the app will come from whichever page it's added to.
models.py Absolute URL Pattern
#models.permalink
def get_absolute_url(self):
return ('cmsplugin_publisher_entry_detail', (), {
'slug': self.slug})
urls/entries.py
from django.conf.urls.defaults import *
from cmsplugin_publisher.models import Entry
from cmsplugin_publisher.settings import PAGINATION, ALLOW_EMPTY, ALLOW_FUTURE
entry_conf_list = {'queryset': Entry.published.all(), 'paginate_by': PAGINATION,}
entry_conf = {'queryset': Entry.published.all(),
'date_field': 'creation_date',
'allow_empty': ALLOW_EMPTY,
'allow_future': ALLOW_FUTURE,
}
entry_conf_detail = entry_conf.copy()
del entry_conf_detail['allow_empty']
del entry_conf_detail['allow_future']
del entry_conf_detail['date_field']
entry_conf_detail['queryset'] = Entry.objects.all()
urlpatterns = patterns('cmsplugin_publisher.views.entries',
url(r'^$', 'entry_index', entry_conf_list,
name='cmsplugin_publisher_entry_archive_index'),
url(r'^(?P<page>[0-9]+)/$', 'entry_index', entry_conf_list,
name='cmsplugin_publisher_entry_archive_index_paginated'),
)
urlpatterns += patterns('django.views.generic.list_detail',
url(r'^(?P<slug>[-\w]+)/$', 'object_detail', entry_conf_detail,
name='cmsplugin_publisher_entry_detail'),
)
views/entries.py
from django.views.generic.list_detail import object_list
from cmsplugin_publisher.models import Entry
from cmsplugin_publisher.views.decorators import update_queryset
entry_index = update_queryset(object_list, Entry.published.all)
views/decorators.py
def update_queryset(view, queryset, queryset_parameter='queryset'):
'''Decorator around views based on a queryset passed in parameter which will force the update despite cache
Related to issue http://code.djangoproject.com/ticket/8378'''
def wrap(*args, **kwargs):
'''Regenerate the queryset before passing it to the view.'''
kwargs[queryset_parameter] = queryset()
return view(*args, **kwargs)
return wrap
The app integration with Django CMS is explained here: http://github.com/divio/django-cms/blob/master/cms/docs/app_integration.txt
It looks like the issue might be that I'm not correctly returning the RequestContext as I'm using a mis of generic views and custom in the application.
The CMS App extension py file:
cms_app.py
from django.utils.translation import ugettext_lazy as _
from cms.app_base import CMSApp
from cms.apphook_pool import apphook_pool
from cmsplugin_publisher.settings import APP_MENUS
class PublisherApp(CMSApp):
name = _('Publisher App Hook')
urls = ['cmsplugin_publisher.urls']
apphook_pool.register(PublisherApp)
Any pointers appreciated, it's proving to be a tough nut to crack!
Looks like it's a bug in the URLconf parser in Django-CMS 2.1.0beta3, which is fixed in dev. The bug only occurs when including other URLconfs from within an app.
UPDATE:
OK, I think your error originates from get_absolute_url:
#models.permalink
def get_absolute_url(self):
return ('cmsplugin_publisher_entry_detail', (), {'slug': self.slug})
I suspect it's because this ultimately calls object_detail which expects a positional parameter queryset (see django/views/generic/list_detail.py). You could try changing this to something like:
return ('cmsplugin_publisher_entry_detail', [Entry.objects.all(),], {'slug': self.slug})
I would double-check that urls/entries.py is actually being imported somewhere otherwise it won't be able to get the reverse match.

Categories

Resources