Django namespaced URLs and parameters - python

I'm encountering an odd problem with namespaced url in Django, and I cannot find what I am doing wrong while it is working on simpler examples and using the
Basically, my project is made of two apps, user and model. In my general urls.py, I defined :
url(r'^model/', include('model.urls', namespace="model")),
url(r'^user/', include('user.urls', namespace="user")),
In the user.urls.py file, I defined the following url:
url(r'^duo/(?P<pseudo>[a-z]+)/$',views.duo, name='duo'),
The duo view is rather simple :
def duo(request,pseudo):
print pseudo
return render(request,"user/duo.html",locals())
Therefore, when I use in my templates:
{% url 'user:duo' lena %}
I expect the url to be resolved as /user/duo/lena. Instead, I got the following NoReverseMatch:
Reverse for 'duo' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'user/duo/(?P<pseudo>[a-z]+)/$']
I take any guess to fix my mistake !

Ok, Pynchia and Bernhard comments help me to fix my bug ! Now, I am using
"{% url 'user:duo' "lena" %}"
in my template and it's running smoothly ! Many thanks to you !

Edited according to the dicussion:
You need to quote your paramater. Also keyword parameters might make things clearer:
{% url 'user:duo' pseudo='lena' %}
If you don't quote the value, Django assumes this is a context variable and as lena is not a context variable in your case this evaluates to None. The error actually tells you, you didn't provide args or kwargs for the reverse lookup.

Related

re_path syntax in *application* urls.py

I have been getting this error for almost a week. I have googled and checked the docs and looked for youtube videos. I cannot find an answer to this seemingly simple and obvious question: What is the syntax for re_path() in the included urls from my apps?
error:
Reverse for 'jhp_url' with keyword arguments '{'slug': ''}' not found. 1 pattern(s)
tried: ['(?P<twodigit>[a-z]{2,3})/courts/(?P<slug>[-a-zA-Z0-9_]+)/$']
That pattern is correct! So obviously, the problem is slug has an empty string. But why? I have it in reverse():
def get_absolute_url(self):
return reverse('jhp_url', kwargs={'slug': self.slug})
Q1:Why isn't it seeing the kwarg from reverse() and using self.slug?
If I try to put self.slug in the view or the url as extra arguments, PyCharm complains.
Putting the namespace in reverse() and the template makes absolutely no difference! I get the same error.
BUT, if I take the namespace out of those two(1) places, I get a different error:
Reverse for 'jhp_url' not found. 'jhp_url' is not a valid view function or pattern name.
(1) as opposed to having it in one but not the other
So it seems like the first error I mentioned here is closer to being right.
My debug_toolbar template context says:
'slug': '^(?P<slug>[-a-zA-Z0-9_]+)/$'
I'm pretty sure that's wrong. It should be the actual slug and not the pattern. That's why I have focused on the app urls.py. But, as I said at the top of this rant. I have not been able to find anything on the syntax of re_path() in the included app urls!
bench.urls.py:
urlpatterns = [
re_path(r"^$", twodigit_testt1, {'slug': r"^(?P<slug>[-a-zA-Z0-9_]+)/$"},
name='tdr'),
re_path(r"(?P<slug>[-a-zA-Z0-9_]+)/$", courtdetail, name='jhp_url'),
Of course I still get these errors, but my point here is that the interpreter runs with that. But when I try things like
re_path(r"^$", twodigit_testt1, {'slug': r'^(?P=slug)/$'}, name='tdr'),
I just get syntax errors.
Finally, please note that these errors are coming because the list template that twodigit_test1 is calling has urls to the individual detail pages in it. If I take the detail urls out of the template, it works. But if I go directly to the detail page, after importing my app views into the project urls, that works, too! It's only the list template + detail urls combination that is the problem - and if you can't list your details on your list page, what's the point? I have tried both the url template tag and get_absolute_url in the template. Finally, I did ask an earlier version of this question. I know some people don't like that but it did not resolve this issue. I have reworked and refocused the question so it is not identical. Plus, I wasn't using re_path() then.

Django reverse url found with arguments but fails with keywords

This is yet another question regarding the error:
Reverse for 'dataPoints' with arguments '()' and keyword arguments '{u'loadID': 5}' not found. 1 pattern(s) tried: [u'loads/dataPoints/']
I've sifted through scads of related post but can't seem to figure out what's going on. The problem is this: in an app using url namespaces, a view template fails with the above error when I try to pass keyword arguments to the url, but works if I use position arguments.
This is what is giving me the above error:
Top-level urls.py:
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
...
url(r'^loads/', include(sig.views.data_loads.urls_data_loads, namespace="loads")),
url(r'^authentication/', include(sig.views.authentication.urls_authentication, namespace="authentication")),
url(r'^account/', include(sig.views.account.urls_account, namespace="account")),
)
urls.py for "loads":
urlpatterns = patterns('',
url(r'^dataPoints', views.DataPoints.as_view(), name='dataPoints')
)
template.html:
points
Then it says it can't find the reverse. Based on some of the related threads I've found, I've tried:
- trying the link without quotes, i.e. {% url loads:dataPoints ... %} (it fails)
- tried different regex patterns, e.g. url(r'^dataPoints(.)*) (still can't find reverse)
I can easily work around this by using positional arguments but it's really bugging me that I can't figure it out. I've used keyword args like this in apps before, and I'm wondering if something is screwy because I'm using url namespaces? Either that or, more likely, I'm doing something completely boneheaded.
EDIT: Adding code for DataPoints view:
class DataPoints(TemplateView):
template_name = "data_loads/templates/dataPoints.html"
def get(self, request):
loadID = request.GET["loadID"]
return self.render_to_response({})
urlpatterns = patterns('',
url(r'^dataPoints', views.DataPoints.as_view(), name='dataPoints')
)
Your modified url does not take any parameter as the one before takes loadID.
So the behavior you are seeing is correct.
To use kwargs, keep your url same and use the template as you are doing
points
I'm taking your comments on Rohans answer into account.
The pattern r'^dataPoints' will match any url that starts 'dataPoints', including dataPoints?load=5, but 'load' will be added to request.GET (so request.GET['load'] is '5'). This is the reason you have never seen anyone doing something like r'^dataPoints?loadID=[0-9]+$ as it is not how url patterns work. Rohans original answer here is correct, you only need to revert to the orginal pattern in urls.py for 'load'. You should try what he has suggested and accept his answer if the error goes away, which I'm sure it will.
OK - I knew it had to be something dumb on my part. I assumed that "keyword arguments" in the context of url dispatching meant GET parameters, not keyword args routed to the get() method. This is also why I was so confused by the comments mentioning a method signature. Ugh. Pretty dumb but hopefully this will help anyone else who makes the same mistake. Anyway, the final answer is that the line in my template file should have read:
points
The post that finally caused this to click in my head was this one. Thanks, everyone, for your help.

Django using url to get only the url part of a named view with parameters

I want to use the {% url %} tag to get the url of a named view that takes a parameter.
I want to get the URL without the parameter and pass the parameter later using javascript. So I don't know the value of the parameter when the template renders ! If I try the url without parameters then it says "reverse not found"... I know I can hard code the url in my javcascript code but that's not DRY !!!
Thanks !
When I've had to do this in the past, I've used a sentinel value for the parameters, ie one that I know will never be passed for real, and used a regex in Javascript to replace it with the real ones.
{% url my_view "anobviouslyfakeparameter1" "anotherparamthatwillneverhappenforreal" %}
You can try the following:
url(r'^test/(\d+)/$', 'test_view', name='test-view'),
url(r'^test/$', 'test_view', name='test-view'),
And return a 404 if the parameter is not provided (in case someone would actually access this uri).

django built in comments

I am using djangos built in comments framework presented in this example: https://docs.djangoproject.com/en/1.3/ref/contrib/comments/example/
And there is a sample code of how to implement a basic comment submission form
{% render_comment_form for entry %}
and when I use this code i get an error that my news model doesent have "add_comment" attribute. but there's no word about it in the example so I am asking how this "add_comment" shoudl work ?
Caught ViewDoesNotExist while rendering: Tried add_comment in module news.views. Error was: 'module' object has no attribute 'add_comment'
You probably have an error in urls.py file in your "news" app. It seems like one of URL patterns there is referring to a non-existing "add_comment" function.
Did you added comments in urls.py?
like so:
url(r'^comments/', include('django.contrib.comments.urls')),

How do I use django.core.urlresolvers.reverse with a function reference instead of a named URL pattern?

In my urls.py file, I have:
from myapp import views
...
(r'^categories/$', views.categories)
Where categories is a view function inside myapp/views.py. No other URLconf lines reference views.categories.
In a unit test file, I’m trying to grab this URL using django.core.urlresolvers.reverse(), instead of just copying '/categories/' (DRY and all that). So, I have:
from django.core.urlresolvers import reverse
from myapp import views
...
url = reverse(views.categories)
When I run my tests, I get a NoReverseMatch error:
NoReverseMatch: Reverse for '<function categories at 0x1082f30>' with arguments '()' and keyword arguments '{}' not found.
It matches just fine if I make the URL pattern a named pattern, like this:
url(r'^categories/$', views.categories, 'myapp-categories')
And use the pattern name to match it:
url = reverse('myapp-categories')
But as far as I can tell from the reverse documentation, I shouldn’t need to make it a named URL pattern just to use reverse.
Any ideas what I’m doing wrong?
Jack M.'s example is nearly correct.
It needs to be a url function, not a tuple, if you want to use named urls.
url(r'^no_monkeys/$', 'views.noMonkeys', {}, "no-monkeys"),
After futher investigation, turns out it was an issue with how I was importing the views module:
How do I successfully pass a function reference to Django’s reverse() function?
Thanks for the help though, guys: you inspired me to look at it properly.
This does work, and all the code that you've pasted is correct and works fine (I just copied it into a clean test/project app and it reversed the URL without any problem). So there's something else going on here that you haven't showed us. Simplify down to the bare-bones basics until it works, then start adding complexity back in and see where it's breaking.
Also, you can do "./manage.py shell" and then interactively import the reverse function and your view function and try the reverse. That'll remove the test setup as a possible cause.
The reverse function actually uses the "name" of the URL. This is defined like so:
urlpatterns = patterns('',
(r'^no_monkeys/$', 'views.noMonkeys', {}, "no-monkeys"),
(r'^admin/(.*)', admin.site.root),
)
Now you would call reverse with the string "no-monkeys" to get the correct url.
Ninja Edit: Here is a link to the django docs on the subject.

Categories