My url is like this below. it accepts /tracks/1 ,/tracks/2
path('tracks/<int:pk>',views.tracks,name='tracks'),
However I want to accept /tracks without pk value.
How can I do this?
Just add another route to the urlpatterns that returns the same view (or any view you want)
path('tracks/<int:pk>',views.tracks,name='tracks'),
path('tracks/',views.your_view ,name='name'),
Related
I have a question about what are differences of redirect and reverse. Does it have influence on performance. And someone could me explain the differences between these 3 examples of code? What is the purpose of them and how can I efficiently apply them.
if 'comment' in request.POST:
form = CommentCreationForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.comment_user = request.user
comment.comment_item = Item.objects.get(id=pk)
comment.save()
//1 return redirect('detail-page', pk=item.id)
//2 return redirect(reverse('detail-page', kwargs={'pk': item.id}))
//3 return reverse('detail-page')
(I can not add any argument to the third one that`s the only difference I noticed).
The two are not the same for a number of reasons. The first one is that reverse(…) [Django-doc] returns a string that is a URL to visit that view. redirect(…) [Django-doc] on the other hand returns a HttpResponseRedirect object [Django-doc]. This object can be returned by the view, and will normally trigger the browser to visit the page specified in the HTTP response. redirect(…) has a special parameter permanent=… that will based on the value return a HttpResponseRedirect (if permanent=False which is the default), or HttpResponsePermanentRedirect for permanent=True.
Another difference is that the reverse(…) works with args=… and kwargs=… parameters to fill in the values for the URL patterns. This is different for redirect(…) where one passes the positional and named parameters just as positional and named parameters. This thus means that if you do a reverse('some_view', args=(some_parameter,), kwargs={'name': other_parameter}), you obtain a HTTP response that points to that URL with redirect('some_view', some_parameter, name=other_parameter).
A redirect(…) does not per se works on a view name. Indeed, if you pass a URL to the redirect(…) function, like redirect('/foo/bar/qux/'), it will construct a HttpResponseRedirect that redirects to the URL /foo/bar/qux. This is different for reverse(…) that only constructs URLs based on the name of the view, and its parameters.
Finally redirect(…) also accepts a model object that has a .get_absolute_url() method [Django-doc] will result in a HttpResponseRedirect that redirects to the URL constructed by that .get_absolute_url() method.
Your first (//1) and second (//2) line will thus produce the same result: a HttpResponseRedirect that redirects to the same URL, whereas the last one (//3) will return a string that contains a URL to the detail-page view.
According to https://docs.djangoproject.com/en/3.2/topics/http/shortcuts/#redirect 1 and 2 are equivalent. I would assume 3 doesn't work as it's missing the ?required? product id?
I an trying to make url router in Django which supports following URLs :
http://localhost:8000/location/configuration
http://localhost:8000/location/d3d710fcfc1391b0a8182239881b8bf7/configuration
url(r'^locations/configuration$',
location_config.as_view(), name="location-config"),
url(r'^locations/(?P<location_key>[\w]+)/configuration$',
location_config.as_view(), name="location-config-uri")
Whenever I tried to hit http://localhost:8000/location/configuration, it picked up the second URL routing format instead of picking up first one.
Error:
TypeError at /locations/configuration/ get() missing 1 required
positional argument: 'location_key'
Can anyone help me here what goes wrong with the url routing format?
Nope, it does pick the first pattern which has no arguments, however you're using the same view in both patterns and location_config view has required argument location_key which is not provided when first pattern matches the URL. That's what error message is saying.
So write another view which will not require location_key argument or alter this view definition: add default to the parameter
def location_config(request, location_key=None):
....
now it is not a "required positional argument".
django Will look for a pk when you are using a detail view by default. you have to override it by using get_object()
in your case
def get_object(self, queryset=None):
location_key = self.kwargs.get('location_key')
obj = Model.objects.get(id=location_key)
return obj
Django 1.8 / Python 3.4
I have a website.html that displays entries from my database, each of which is identified by its ID. Now, at the end of each displayed entry I have a link to an "edit" view, looking like this:
<td>edit</td>
The link is working fine and leads to the correct view:
def edit(request, object_id):
implemented in views.py. There some code is executed correctly too, and in the view's last line I have:
return redirect('website.html')
Obviously, after the chosen entry has been edited I want my website.html with the edited entry being displayed in the browser again: 127.0.0.1:8000/website/. However, what happens is that I get a Page not found (404) error, with the information:
Requested URL 127.0.0.1:8000/website/2/website.html
The "2" here is the ID of the entry.
Maybe I have the wrong idea about how redirects work, but I was assuming that instead of calling the respective view's url from url.py it would open the url provided in the redirect() function?!
What happens, though, is that this url gets appended to the view's url!
Here is my urls.py:
from django.conf.urls import include, url
from django.contrib import admin
from www.list.views import website, edit
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^website/$', website, name="website"),
url(r'^website/(?P<object_id>\d+)/$', edit, name="edit"),
]
I'm pretty sure the third url entry is causing the problem but I have absolutely no idea how to change it for the redirect to work. Also, the edit view doesn't have an actual website (template), but I'm supposed to provide a URL for it, so this was the best I could think of.
The way this should work is: Click the "edit" link on website.html, the code from the edit-view is being executed, and, afterwards, the website.html with the change in the database entry gets displayed again.
^^ How to achieve this? Any help is appreciated!
Redirect uses names or absolute URLS. You should either use the name of your URL:
return redirect('website') # since name="website"
or an absolute URL, like:
return redirect('/website/')
you can use the reverse function instead of redirect
from django.core.urlresolvers import reverse
return reverse('website')
I found the mistake and the solution:
At the end of the edit-view it's correct to write "return redirect('website')". However, just as I assumed, the URL of edit in urls.py was wrong.
Instead of
url(r'^website/(?P<object_id>\d+)/$', edit, name="edit"),
it should just be
url(r'^(?P<object_id>\d+)/$', edit, name="edit"),
Thank you nonetheless!
I have the form which i am showing by normal view. Then i am send the GET parameters to djnago ChangeList view like django does for lookups like this
student/?region__id__exact=1&status__exact=Published
now is there any way to remove that from the URL in the address bar.
I don't users to see what i am doing
The whole point of GET is that they are retrieved from the URL itself, removing them from the URL removes them entirely.
If you want them 'hidden' you will need to use POST.
The HTTP GET method of form submission passes the information from template to views through URL. If you want to "hide" information from URL use POST instead. In your form do like this:
<form action="/view_name/" method="post">
and in views:
request.POST['name']
I have my URL defined as follows:
(r'^article/edit/(.*)/$', 'mysite.views.edit_article')
And the function defined as:
def edit_article(request, article_id):
However, it seems that any request to this page results in the wrong value being passed in for article_id. If I redefine my URL as
(r'^article/(.*)/$', 'mysite.views.edit_article')
Minus the "edit/" it seems to work. Any suggestions on how to fix this?
Try this:
url (r'^article/edit/(?P<article_id>\d+)$', 'mysite.views.edit_article'),
Take a look at the Named Groups in the Django documentation