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
Related
I have the url patterns in my project urls.py
url(r'^', include('app.urls')),
url(r'^api/app/', include('app.url.router_urls')),
and in the app.urls i have something like
url(r'^api/app/user$', views.user_validator),
and in the app.url.router_urls i have something like
url('^v1/', include('app.url.app_v1.urls'))
I have a question around these.
so when the request is BASE_URL/api/app/{user} which url will be mapped to this?
and how about BASE_URL/api/app/v1/ which url will be mapped.
this will map first with ^ right and will use the app.urls for both?
thanks
Django will fire the first view for which the URL matches. It thus evaluates the urls top-to-bottom.
It will thus first look to the included app.urls and if that matches (if you visited hostname/api/app/user, it will "fire" that view.
Note that here your user is not a variable, this is simply the word user, so if you visit {user}, it will keep looking, but since none of the patterns "fire", it will thus return a 404.
You can work with URL parameters, with:
url(r'^api/app/(?P<user>[\w{}]+)$', views.user_validator),
If we do this however, it will also match with hostname/api/app/v1, since then it sees that [\w{}]+ matches with v1.
Therefore it is important to order the url patterns from more specific to less specific, or even better: design the URL patterns such that there is no overlap.
Note: As of django-3.1, url(…) [Django-doc] is
deprecated in favor of re_path(…) [Django-doc].
Furthermore a new syntax for paths has been introduced with path converters: you
use path(…) [Django-doc] for that.
In my urls.py I have:
urlpatterns = [
url(r'^admin/', admin.site.urls, name='admin'),
url(r'^django-admin/', RedirectView.as_view(url='/admin/', permanent=True)),
]
So if I go to localhost:8000/django-admin/ it successfully redirects me to localhost:8000/admin/, and if I go to localhost:8000/django-admin/my-app/ it also redirects me to localhost:8000/admin/.
How could I make localhost:8000/django-admin/my-app/ go to localhost:8000/admin/my-app/? And the same for every possible subpath e.g. localhost:8000/django-admin/my-app/my-view, localhost:8000/django-admin/another-app/, etc?
According to the docs something like this should work, you can capture groups from the path and pass them to the url
The given URL may contain dictionary-style string formatting, which will be interpolated against the parameters captured in the URL. Because keyword interpolation is always done (even if no arguments are passed in), any "%" characters in the URL must be written as "%%" so that Python will convert them to a single percent sign on output.
url(r'^django-admin/(?P<rest>.*)', RedirectView.as_view(url='/admin/%(rest)s', permanent=True)
This website is particularly useful for figuring out how the built-in class-based views work http://ccbv.co.uk/projects/Django/2.2/django.views.generic.base/RedirectView/#get_redirect_url
What is the best way to redirect a url like "mywebsite.com///" to "mywebsite.com/" in django?
Is there a setting that I can use in the settings.py file that is kind of the opposite of APPEND-SLASH or do I have to use
from django.views.generic.simple import redirect_to
and add a urlpattern in the urls.py file?
Edit:
I not trying to just make the webpage the same as "mywebsite.com/" i'm trying to get the actual url to change to "mywebsite.com/". Sorry for the confusion.
If you want to do this at the application level I'd avoid creating new urlconf rules, specially if it's a global thing.
You can make your own middleware to handle this redirect automatically, as django does in the common middleware for appending slashes using the APPEND_SLASH setting here is the code for reference: https://github.com/django/django/blob/master/django/middleware/common.py#L66-80
Also you may find the solution on this blog post useful: http://gregbrown.co.nz/code/append-or-remove-slash/
You should add a url pattern in the urls.py file that will match this url, with the added slashes, if you wish.
Each pattern is just a regular expression, so you can tell it to match any url with extra slashes pretty easily.
urlpatterns = patterns('django.views.generic.simple',
('^your/url/*$', 'redirect_to', {'url': '/your/url/'}),
)
By adding /* to the url pattern it will match /your/url/ with any number of slashes after it.
So in Django the two lines of url code below work the same:
urlpatterns = patterns('',
url(r'^login/$', 'django.contrib.auth.views.login'),
(r'^login/$', 'django.contrib.auth.views.login')
)
AFAIK, the only difference is I can define name='login' so I can use it for reversing url. But besides this, is there any other differences?
There is no difference whatsoever. Have a look at the patterns function in django.conf.urls.__init__.py, if your url is a list or tuple then it is wrapped up by the url function anyway before being appended to the list of available patterns.
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?