I have an issue where I need to pass in query parameters for a GET request, but Django is not resolving the URL correctly to the view.
My urls.py looks like this:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
url(r'^confirm_cancel',
'myapp.views.confirm_cancel_method',
name='myapp_confirm_cancel'),
)
When I goto /confirm_cancel?some_id=x I get a 404, telling me "No MyModel matches query." When I set a breakpoint in my view handler, it does not get hit when I goto that url.
However, if I goto /confirm_cancel/x/, my view breakpoint does get hit.
One more thing to note, this worked in Django 1.1, but is now broken since I upgraded to 1.2.
Any thoughts?
Thanks!
I don't think the problem is with your url. Are you using a shortcut like get_object_or_4o4 somewhere in your view? For example:
get_object_or_404(MyModel, pk=99)
would result in a "No MyModel matches given query, if there wasn't a record in your table with a primary key of 99.
We need to see what's in the corresponding view function.
Ideally, it should look something like this:
def confirm_cancel_method(request, some_id=None):
some_id = request.REQUEST.get('some_id', some_id)
some_record = get_object_or_404(SomeModel, pk=some_id)
...
update
Sorry, just saw your note about the breakpoint. One thing I'd recommend is changing the config to this:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
url(r'^confirm_cancel/?$',
'myapp.views.confirm_cancel_method',
name='myapp_confirm_cancel'),
)
Adding /?$ at the end means that only /confirm_cancel or /confirm_cancel/ will match the url. Right now because you don't have the ending $ anything starting with confirm_cancel will match. Fixing the pattern will at least resolve this issue.
I had copied out all the other url patterns in the urls.py in my post.
Turns out that the issue was that I had a r'^(?P<my_id>\w+)/?$' for one of the urls at the top of the urlpatterns.
Next time I'll learn to paste everything instead of cherry picking what I think are the offending lines of code.
Strange that this did not cause Django 1.1 to break... I guess it was a bug that was fixed in 1.2
Did you check if this was a case of the trailing slash?
Related
I am using UpdateView for my update page, but I get this error:
Field 'None' expected a number but got 'update'.
my urls.py looks like this:
path('post/<pk>/update/', PostUpdateView.as_view(), name='post_update'),
Everything works fine if I change my update URL to anything other than "post". For example, this works fine:
path('abcxyz/<pk>/update/', PostUpdateView.as_view(), name='post_update'),
I would like to use the word "post" in URL, because i also use it in the other URLs and they work just fine (except for delete view, which gives me the same error). Is there any way to fix this error without changing the URL?
Note: It has worked before, but it broke at some point when I was trying to use django-PWA. I'm not sure if this is related though.
Thank you for your help!
This is likely because you have another path like:
path('post/update/update/', PostUpdateView.as_view(), name='post_update'),
or something similar. It is possible that one or both update/s are URL parameters.
If you then for example visit post/update/update, and your PostUpdateView is defined first, the it will trigger the view with pk='update'.
If the primary key is simply a number, you can make use of the <int:…> path converter to prevent triggering the view when pk is something else than a sequence of digits:
path('post/<int:pk>/update/', PostUpdateView.as_view(), name='post_update'),
EDIT: Based on your comment, there was another view before this one with:
path('post/<year>/<month>/', FilteredPostListView.as_view(), name='filtered_post')
If one thus visits post/123/update, it will trigger the FilteredPostListView with 123 as year, and update as month, and hence it will raise an error.
You can put the path below that of the ProductUpdateListView, and you furthermore might want to use the <int:…> as well to only trigger the view when both parameters are sequences of digits:
path('post/<int:year>/<int:month>/', FilteredPostListView.as_view(), name='filtered_post')
I'm building a tool using Django that works with the part numbers that my company uses, one set of part numbers includes /'s which I didn't realize when I set up the url to access the part summary.
Now when try to pass one of those part numbers it breaks things, is there a way to work around this? I'd like to avoid changing the part number or adding a unique id with no other meaning to the model.
an example part number that causes the problem is P-030-P-401/ND the url pattern is /parts/
Thanks in advance
If you are allowed to change the route a bit, this is an option with just a few characters difference:
www.domain.com/parts/?part_id=P-030-P-401/ND
Example setup:
urls.py
urlpatterns = [
# other paths here
path("parts/", view_test),
]
views.py
def view_test(request):
part_id = request.GET.get("part_id")
return render(request, "parts/test.html", {"part_id": part_id})
test.html
{{part_id}}
Depending on browser settings maybe replace / with %2F, but it's working with the slash for me on Firefox.
i'm adding forms to my app to modify my lobbys (my custom model).
In urls.py, here is my urlpattern:
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^lobbys/$', views.LobbyListView.as_view(), name='lobbys'),
url(r'^lobby/(?P<pk>[\w-]+)/$', views.LobbyDetailView.as_view(), name='lobby-detail'),
url(r'^lobby/create/$', views.LobbyCreate.as_view(), name='lobby_create'),
url(r'^lobby/(?P<pk>\d+)/update/$', views.LobbyUpdate.as_view(), name='lobby_update'),
url(r'^lobby/(?P<pk>\d+)/delete/$', views.LobbyDelete.as_view(), name='lobby_delete'),
]
The problem is the following:
The third url is supposed to link to a single lobby template identifed with a UUID field as the primary key. Without the three last lines everything worked fine, but when I added my three urls for the forms, I'm getting the error
Exception Value: ["'create' is not a valid UUID."]
I understand urls.py is taking "create" as a primary key instead of considering it as an urls to an other view.
How can I bypass this problem?
Thank you very much.
You need to change the ordering of the url patterns
url(r'^lobby/create/$', views.LobbyCreate.as_view(), name='lobby_create'),
url(r'^lobby/(?P<pk>[\w-]+)/$', views.LobbyDetailView.as_view(), name='lobby-detail'),
The issue is, since lobby-detail is looking for a alphanum pattern, it also matches the pattern lobby/create. The order matters in the regex patterns, so lobby_create is never matched. By changing the order, the issue would be resolved
i am trying to use ajax pooling on my site (setTimeout) alongside django-session-security . In the documentation there is a mention of SESSION_SECURITY_PASSIVE_URL but i can't seem to get it to work.
My settings:
SESSION_SECURITY_WARN_AFTER = 15
SESSION_SECURITY_EXPIRE_AFTER = 21
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SESSION_SECURITY_PASSIVE_URL = ['http://localhost:8000/core/notice/check/', 'core/notice/check/', '/core/notice/check/']
My javascript:
setTimeout(function(){
get_notifications();
}, 2000);
Any ideas what i am doing wrong?
It seems that it's just because your settings parameter name is missing the ending 's'. It should be 'SESSION_SECURITY_PASSIVE_URLS' instead of 'SESSION_SECURITY_PASSIVE_URL' in your case. Consider the source code here.
Other than that I believe you can safely remove redundant elements from the SESSION_SECURITY_PASSIVE_URLS list and leave just the '/core/notice/check/' entry there. Again, as we can see from the source code the decision of whether request 'is passive' is made by checking the request.path against the list of values from the settings.
Can't comment, thus attempting to answer here. Have you added {% include 'session_security/all.html' %} to your (base) template? Also do you have added session_security URLs in appropriate urls.py file?
SESSION_SECURITY_PASSIVE_URLS allows you to add static urls. However, most urls in Django are anything but static. How would you add dynamic urls to this list to bypass session update. For example in url /category/1/product/5/, 1 and 5 are dynamic ids but I would like to skip any url that matches the pattern
'/category/(?P<cat_id>[\d]+)/product/(?P<product_id>[\d]+)/'
This is unlikely, but if you are using django-ajax middleware AJAXMiddleware, it conflicts with session_security mechanism, and either the session expiry notification might not appear or session expiration might not work altogether. I had to remove AJAXMiddleware to make session_security work again.
I'm trying to get people on my site to access an entirely separate part of the site based on what user group they belong too. Here is the logic I've written so far:
if request.user:
if request.user.groups.filter(name='A').count() >= 1:
return HttpResponseRedirect('/pageA')
elif request.user.groups.filter(name='B').count() >= 1:
return HttpResponseRedirect('/pageB')
else:
return HttpResponseRedirect('/login')
And then urls:
url(r'', 'main.views.getIndex'),
url(r'', include('a.urls')),
url(r'', include('b.urls')),
So basically, I have group A & group B - user can access "A" page and "B" page accordingly if they belong to the respective user group. Otherwise, they have to login (placeholder denial page).
The logic seems to make sense, but I keep getting "too many redirects" error. In fact, the page actually gets to the statement I want it too but then upon returning HttpResponseRedirect, it stops working.
Your help is much appreciated.
The following pattern will match all urls
url(r'', 'main.views.getIndex'),
So if the getIndex returns a redirect, you will get an infinite redirect loop.
If you only want the url pattern to match the index url (i.e. /), then change it to:
url(r'^$', 'main.views.getIndex'),
The caret ^ matches the beginning of the string and the dollar $ matches the end of the string. Therefore ^$ only matches the empty string ''. By contrast, the regex r'' matches all strings.
Well I don't know what code you have in a.urls and b.urls, but I will give you the way I almost always use when I should apply a redirect. It is only a new way you can have, of course. For example supposing you have this entry on a.urls:
from django.conf.urls.defaults import *
urlpatterns = patterns('appA.views',
url(r'^pageA/$', 'pageA_view', name='pageA'),
)
you can apply this:
from django.shortcuts import redirect
# In your code
if request.user.groups.filter(name='A').count() >= 1:
return redirect('pageA')
It is another way you can accomplish this task. You can follow your idea too, but for a better understanding it would be useful to see what you have on your a.urls and b.urls.
Well, I just see the answer after I posted me response. Anyway, maybe it can help to someone.