How to get data from url in django without query parameters - django

sorry for my noob question as I am just starting to learn Django. I would appreciate if someone could tell me how can i change data dynamically on page in django. Let me clear this:
What I want:
When url is http://localhost/data/1111, page data should be like data is 1111.
When url is http://localhost/data/2222, page data should be like data is 2222.
What I did:
def index(request):
print(int(request.GET["data"])) # for debugging only
return HttpResponse("data of Page")
and url was:
path('<int:data>', views.index, name='index')

Since you have a value in your url, the <int:data> part, that needs to be captured by the view, which means your view function has to be aware of the extra parameter.
So, the correct view for this would be:
def index(request, data):
print(data) # data is already converted to int, since thats what you used in your url
return HttpResponse(f"data is {data}")

Since you don't want to pass query parameters in your url, change your url to look like this
path('data/', views.index, name='index')
def index(request):
print(int(request.GET["data"])) # for debugging only
return HttpResponse("data of Page")
Note that on GET['data'], data is not what is on the url pattern but rather it should be a input name on the form like <input name='amount' type='number' />
Now you can access amount like this
def index(request):
print(int(request.GET["amount"])) # for debugging only
return HttpResponse("data of Page")

Related

redirect vs reverse django

I have experienced using reverse within get_absolute_url method in the model, but I wish I have an idea about the difference between reverse and redirect, I have tried to search on google about it but there is almost nothing
I don't know what should I write also to convince stack overflow that I don't have any other description
Reverse and redirect have a different meaning. Here is a simple explanation:
reverse in Django is used to find the URL of a given resource. Let's say that you have a blog website and from the main page, you want to provide links to your blog posts. You can of course just hard-code /posts/123/ and just change the ID of your blog post in URL, but that makes it hard to change your URL for the post in the future. That's why Django comes with reverse function. All you need to do is to pass the name of your URL path (defined in your urlpatterns) and Django will find for you the correct URL. It is called reverse because it is a reverse process of determining which view should be called for a given URL (which process is called resolving).
Redirects are not specific to Django or any other web frameworks. Redirect means that for a given URL (or action), the user should be instructed to visit a specific URL. This can be done by sending a special redirect request and from there the browser will handle it for the user, so no user action is required in that process. You can use reverse in redirect process to determine the URL that the user should be redirected to.
GwynBleidD has given you the answer, but there is a reason why you might be getting confused. The Django redirect shortcut accepts arguments in several different forms. One of them is a URLpattern mane, with arguments, that is then passed to reverse to generate the actual URL to redirect to. But that's just a shortcut, to enable a common pattern.
here's an example
app/views
#imports
def indexView(request):
....
return render(request, 'index.html', context)
def loginView(request):
....
return redirect('index')
def articleDetailView(request, id):
....
return redirect(reverse('article-comments', kwargs={'id':id})
def articleCommentsView(request, id):
....
return render(request, 'comment_list.html', context)
proj/urls
#imports
urlpatterns = [
....,
path('', include(app.urls))
]
app/urls
#imports
urlpatterns = [
....,
path('index/', index, name='index'),
path('login/', loginView, name='login'),
path('article/<int:id>/detail', articleDetailView, name='article-detail'),
path('article/<int:id>/comments/',articleCommentsView, name='article-comments')
....,
]
For loginView redirect will return url as-is i.e. 'index' which will be appended to base(project) urlpatterns. Here redirect(reverse('index')) will also work since kwargs is None by default for reverse function and 'index' view doesn't require any kwarg. It returns '/index/' which is passed to redirect(which again will be appended to base urls).
One thing to note is that reverse is used to make complete url - needed for redirect - that is shown in 'articleDetailview'.
The most basic difference between the two is :
Redirect Method will redirect you to a specific route in General.
Reverse Method will return the complete URL to that route as a String.

Remove "?id=" from dynamic URLs

I'm pretty new to django and i'm working on a website that needs a dynamic URL for a database table, and it all works fine, but i would like to know how to remove the "?id=" from the url, so rather than
localhost:8000/dynamicurl/?id=XXXXX
The url becomes
localhost:8000/dynamicurl/XXXXX
Instead
I did a fine amount of searching in the documentation and didn't find a lot, though it's pretty likely i missed something.
EDIT:
thanks everyone for helping, the simplest answer was to remove the object i was using to fetch the ID and just replace it for ID in evert instance,
so my url became
url(r'^dynamicurl/(?P[0-9]+)/$', views.dynamicurl)
and my view became
def dynamicurl(request, id):
i'm like very very new to django FYI
you can capture a variable in url definition in the apps urls.py file. It would look something like this:
url(r'^dynamicurl/(?P<id>[0-9]+)?$', dynamicurl, name = 'dynamicurl'),
then in your view function you receive that parameter:
def dynamicurl(request, id):
If you are talking about how to change your url inside the urls, I suggest you to use code that already answered above: https://stackoverflow.com/a/41988051/6396981
But, if you talking about how to redirect localhost:8000/dynamicurl/?id=XXXXX to localhost:8000/dynamicurl/XXXXX, hope this usefull..
1. views.py
from django.http import HttpResponse
from django.views.generic.base import RedirectView
from django.core.urlresolvers import reverse
class RedirectView(RedirectView):
permanent = False
def get_redirect_url(self):
get_id = self.request.GET.get('id')
if get_id is not None:
return reverse('redirected_page', kwargs={'id': id})
return reverse('origin_page')
def redirected_view(request, id):
# your final view goes here...
return HttpResponse("You're looking for id: %d." % id)
2. urls.py
from django.conf.urls import url
from yourapp.views import views (RedirectView, redirected_view)
urlpatterns = [
# first view the pool to doing redirection
url(r'^pool/$', RedirectView.as_view(), name='origin_page'),
# the final url
url(r'^pool/(?P<id>[\d]+)/$', redirected_view, name='redirected_page'),
]

Providing parameters when reverse_lazy-ing a success_url redirect

TLDR: I want to be able to provide slug in reverse_lazy('view', kwargs={'slug':'my_page'}) like this: reverse_lazy('view').apply(kwargs={'slug':'my_page'}), after creating the lazy object.
I have the following url pattern that includes a slug to identify a page model instance:
url(r'^(?P<slug>'+settings.SLUG_PATTERN+')/$', views.MyView.as_view(), name='view'),
I have another view for editing the page:
url(r'^(?P<slug>'+settings.SLUG_PATTERN+')/_edit/$',
views.MyEditView.as_view(success_url=reverse_lazy('view')), name='edit'),
Note the addition of success_url so that when I submit the form with the new content I'm redirected to the now-edited page. In case I ever change my view url pattern I don't have to worry about updating the redirect for my edit url.
After the form is validated and saved, the view grabs the success url to be used in a HttpResponseRedirect. However just the name 'view' isn't enough to identify the URL. I also need to know the slug name which is stored in my page model's slug field.
A similar question is here: success_url in UpdateView, based on passed value
The answers suggest writing a custom get_success_url for every view, but there must be better approaches.
In the generic views in django's edit.py there's this:
url = self.success_url.format(**self.object.__dict__)
If success_url were given as a hard coded URL but with a slug identifier such as '{slug}/' this would replace it with the slug field in my model. That's very close to what I want, but I don't want to hard code my URL. This brings me to my question:
How can I pass in parameters to a reverse_lazy object? I would use this in my base view's get_success_url with self.object.__dict__ and it'd just work everywhere.
Moreover if my slug string was stored on separate Slug model I might want the success URL to be '{slug.name}/'. With the above approach I could supply a mapping between the URL parameters and model attributes:
redirect_model_mapping = {'slug': '{slug.name}'}
...
def get_success_url(self):
url = self.success_url
if is_a_lazy_redirect(url):
url = url.somehow_apply_parameters(redirect_model_mapping)
return url.format(**self.object.__dict__)
I would like somehow_apply_parameters to be equivalent to originally calling reverse_lazy('blog:view', kwargs=redirect_model_mapping). However I don't think this should be in urls.py because it shouldn't have to know about the mapping.
This is a hack, but does what I want...
class MyView(FormMixin, ...):
#this is actually set on child classes
redirect_model_mapping = {'slug':'{slug.name}'}
def get_success_url(self):
url = self.success_url
if url is not None:
if hasattr(self.success_url, '_proxy____kw'):
url_parameters = dict((k, v.format(**self.object.__dict__)) for k, v in six.iteritems(self.redirect_model_mapping))
url._proxy____kw = {'kwargs': url_parameters}
url = force_text(url)
else:
url = url.format(**self.object.__dict__)
else:
raise ImproperlyConfigured("No URL to redirect to.")
return url
It replaces the kwards parameter normally passed to reverse_lazy but after it actually has the values it needs. As reverse_lazy also requires the string to match the regex, I had to make the mapping between url parameters and the values in the models first.
I'd quite like an approach that doesn't need to write to _proxy____kw.

How to pass dictionary of values when redirecting user to a url in django

Below is the code from views.py where I am using render_to_response to direct the user to done.html along with a dictionary of variables. But, I actually want to direct the user to a url /home_main/#signin_completeand pass the dictionary of variables that are callable. Can someone please suggest if there is a way of doing this ?
def done(request):
"""Login complete view, displays user data"""
scope = ' '.join(GooglePlusAuth.DEFAULT_SCOPE)
return render_to_response('done.html', {
'user': request.user,
'plus_id': getattr(settings, 'SOCIAL_AUTH_GOOGLE_PLUS_KEY', None),
'plus_scope': scope
}, RequestContext(request))
EDIT
My requirement is to render a second page (signin_complete) from a multipage html (home_main.html). Currently, I am achieving this by redirecting the user with HttpResponseRedirect as shown below. But, I would also like to pass a callable dictionary that I can use in the second page of the multipage html.
Here is a link that gives more information of a multipage html under multipage template structure.
def done(request):
"""Login complete view, displays user data"""
scope = ' '.join(GooglePlusAuth.DEFAULT_SCOPE)
return HttpResponseRedirect('/home_main/#signin_complete')
Below is the dictionary that I would like to pass to the second page (sign_complete) in the multi page html.
{
'user': request.user,
'plus_id': getattr(settings, 'SOCIAL_AUTH_GOOGLE_PLUS_KEY', None),
'plus_scope': scope
}
The session is the place to store data between requests.
# in done():
request.session['dict_to_save'] = my_dict_to_save
return redirect('/new/url/to/redirect/to')
# in the new view:
values_from_session = request.session.pop('dict_to_save', None)
It would be much better if you would redirect request inside done() method, like the docs advises you to do.
This solves your issue as well, since you can define your own url to redirect to, there's related SO question of how to add hash tags when redirecting.

Django url: I want to match this param, how to write the regex?

url scheme sample:
http://domain/tests/?_=1111111&data=3333333&status=22222222
In view, I need data and status, any approach is welcome! All the params are integers.
Your data passed as GET parameters does not need to be matched in urls file.
urlpatterns += patterns(
('^tests/$', 'app.views.test'),
)
You will have that data in your view as: request.GET.get('_', None), ...
Your can write a form which will help you to validate and clean up the data and use it like this in your view:
form = some_form(data=request.GET)
if not form.is_valid():
raise InvalidRequest()
data = form.cleaned_data
If that's the url the params are accessible through the request.GET dictionary in the view method.
def my_view(request):
print request.GET['data']
Of course if you need to validate whether the elements are in the dictionary('data' in request.GET) and convert them to int prior using them like that. int(request.GET['data'])