Cannot have any URLs with slugs. NoReverseMatch - python

I'm a begginer grasping at straws with difficulty dealing with the django slug url system and these NoReverseMatch errors that make no sense to me even after reading the docs.
I have a django project. In one of the views, I pass a list of geoJSON features into a template, and show them on a map. I want to have each feature act as a clickable 'link' to a view that will show stuff about it. The following is part of the template that has those features that I want to click on:
//part of the template:
<script type="text/javascript">
...
function onEachFeature(feature, layer) {
layer.on('click', function (e) {
window.location.href = "{% url 'polls:areadetail' feature.properties.myslug%}";
});
}
(I have confirmed that feature.properties.myslug does in fact contain the slug I want).
The url pattern I want to go to:
urlpatterns = [...
url(r'^areadetail/(?P<areaslug>[-\w]+)/$', views.AreaDetail, name='areadetail'),]
And the view it relates to:
def AreaDetail(request, areaslug):
area = get_object_or_404(Area, nameslug=areaslug)
return render(request, 'polls/areadetail.html', {'area':area})
The issue I get is, by doing what I show and placing that url reference inside that template I show above, that I want to be able click on, that template won't even work at all, giving me a 'Error during template rendering' full page error info that starts with:
NoReverseMatch at /polls/areas/
Reverse for 'areadetail' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'polls/areadetail/(?P[-\w]+)/$']
Any help would be immensely appreciated
EDIT part1: As I've said in response to falsetru, I'm sure feature.properties.myslug has in fact got a slug expression in it.
EDIT2: Based on something I found in a django ticket, I've made a slight change in the url regex at urls.py, from (?P<areaslug>[-\w]+)/$ to (?P<areaslug>[-\w]+)?/$ and now the error is:
Page not found (404)
Request Method: GET Request URL: http://127.0.0.1:8000/polls/areadetail// Raised by: polls.views.AreaDetail
Is it possible that because the "{% url 'polls:areadetail' feature.properties.myslug%}" bit is inside javascript, that feature.properties.myslug is not being inserted there correctly? Like some sort of brackets are needed here?

According to the error message, feature.properties.myslug is empty or has no value.
Make sure the feature.properties.myslug is passed correctly from view.
Comment out {% url .. %} temporarily.
Print {{ feature }}, {{ feature.properties }}, {{ feature.properties.myslug }} to see if which part is missing.
Fix view accordingly.
Uncomment {% url .. %}.

After some more digging around I've found the answer to why doesn't this work in another question at:
How to pass javascript variable to django custom filter
The answer to it by Ludwik Trammer says:
Django templates are build on the server side, while JavaScript is executed on the client side.
That means that template code is always executed before JavaScript (as
it is executed by the server, before the page is sent to the client).
As a consequence it is absolutely impossible to mix JavaScript and
Django code the way you want to.
Which clearly applies here. I was focused on problems with the URL template, regex on the urls.py file etc. when the problem was that no matter what I did, because it's in a javascript section, run client-side, that URL template will always be incomplete no matter what I do, therefore being an impossible solution to what I want.

Related

Django no reverse match at /

I'm trying to make a picture the url to the post the picture represents, and I must be doing something wrong, but I don't know what.
I am getting this error when trying to visit the home page of my site.
Error during template rendering
In template .../home.html, error at line 48
Reverse for 'view_post' with keyword arguments '{'post_id': ''}' not found. 1 pattern(s) tried: ['post/(?P[0-9]+)/$']
and the code it showcases
<img src="media/{{ item.image }}">
Also this is my view
def view_post(request, post_id):
post = get_object_or_404(Post,id=post_id)
return render(request,'gram/view_post.html',{'post': post})
And url
url(r'^post/(?P<post_id>[0-9]+)/$', views.view_post, name='view_post'),
Thank you for your help.
I make some assumptions based on your code examples. This line:
post = get_object_or_404(Post,id=post_id)
says that the class Post has a property id. However in your template you call post.post_id. Assuming that post is an object instance of the class Post, it should have the property id. Probably there is no such property like post_id in the class Post.
This means that in the template post.post_id won't return an output. Your urls, which are not shown here, expect an integer ['post/(?P[0-9]+)/$']. Therefore the error is thrown.
Try this snippet:
{% url 'view_post' post_id=post.id %}
and check what happens.
As I said, this is based on some presumptions and I don't guarantee success.
Turned out I'm just stupid and made it hard for myself. The problem was I've done <a href in my home.html and home view didn't know what post.id is - obviously. The problem is fixed.

Django default login view always populates the next field

I'm using the default django authentication system with little customization. The core functionality to login and logout is working as expected. The problem is with the following snippet in my login form template:
{% if next %}
<p>Please login to see this page.</p>
{% endif %}
This is adapted from the example login view provided in the official documentation. The idea is that if the user tried to access a protected page without logging in, he/she would be redirected to the login page and the next parameter is set to the protected page's url. This is working fine.
However, when the user clicks on the login url and navigates directly to the login url, the above error message should not be displayed. But in this case, the next parameter is being set to the LOGIN_REDIRECT_URL from settings.py and we see this error message.
I tried to debug to find where the problem is, and found it in django.contrib.auth.views.LoginView class. This class has a method get_success_url which gets the redirect url either from the next parameter or from the LOGIN_REDIRECT_URL. This method is being used to populate the context for the login form in the method get_context_data, which, in my opinion is incorrect. The dispatch method also uses the get_success_url to get the redirect url, which is correct because the purpose is to actually redirect.
I'm not sure if my explanation is clear, let me know if it isn't. Is there a workaround for this? Should I submit a bug report for this?
Using:
Python: 3.6 (Anaconda3, 64 bit)
Django: 1.11.1
django-registration: 2.2
Raised Django bug https://code.djangoproject.com/ticket/28229.
This is not a solution but more like a workaround:
Assuming that your LOGIN_REDIRECT_URL is set to /, you could write {% if next != "/" %} instead of {% if next %}.

url template tage variable not being parsed django

I am trying to dynamically generate links in my template of the form ..../hub/username/ but am always getting back only ..../hub for some reason. I have read through the docs several times and it seems very clear what to do, but I am just making some mistake somewhere I suppose!
Please Help!
I have in my urls:
urlpatterns = patterns(
'',
url(r'^hub/(.+)/$', 'hub.views.hub_view', name="hub"),
...
...
)
I have in my template:
<li><a id="todoMenuButton" href="{% url 'hub' user.username %}">ToDo</a></li>
template context preprocessors is enabled in my settings:
TEMPLATE_CONTEXT_PROESSORS = (
'django.core.context_processors.request',
)
Thanks!
Instead of adding the request context processor to the default set, you've overwritten the defaults with that single one. That means there is no user variable defined in the context. You could use request.user instead, but it would be better to fix your seeing as there are other useful processors you are missing out on (eg debug).
It was a simple mistake, I was using the todo button instead of the hub button :/
Sorry!
Thanks!

Django url template confusion

Okay I am having a bit of an issue.
I want to create a button with a link, and right now I am using action={% url views.contest_overview %} in hopes that the reverse lookup by Django will match (r'^category/$', views.contest_overview), in my urls.py. However, this is not working and I can't figure out the proper nomenclature, despite numerous guesses.
The error I get (with my best guess above) is:
Caught NoReverseMatch while rendering: Reverse for
'views.contest_overview' with arguments '()' and keyword arguments
'{}' not found.
Thank you very much for your time!
Use the application name in the url tag, e.g. {% url myapp.views.contest_overview %}
This is what I usually do; I give names to my url. For example:
url(r'^account/register/$', 'someapp.views.register_view', name='account_register'),
Therefore in template, I can do this:
{% url account_register as url_acc_register %}
<html>
..
..
Some link

How to get the current URL of a page in a Django template?

I know there is another question with virtually the same title as mine but the solution in that one didn't work for me. My url is like this:
http://domain.com/videos/dvd/1/
If I use either {{baseurl}} or {{ request.get_full_path }} I get just this part:
http://domain.com/videos/
How can I get the entire url? I need to be able to do this from the template level.
EDIT
P.S. it should disregard any parameters that may be in the url.
You could get it in your view and pass it along into your template context so that it is available to you there.
https://docs.djangoproject.com/en/1.3/ref/request-response/#django.http.HttpRequest.build_absolute_uri
full_url = request.build_absolute_uri(None)
# pass full_url into the template context.

Categories

Resources