https://xxxx/category_check_view/?item_id=2
Above is a sample of URL pattern. How should i configured my URL in order to enable it to redirect to the right view?
I seem to get it working for a url like this https://xxxx/category_check_view/2/ only so far.
You can pass parameters to a view either in the url:
/category_check_view/2
Or via GET params:
/category_check_view/?item_id=2
GET params are not processed by the URL handler, but rather passed directly to the GET param dict accessible in a view at request.GET.
The Django (i.e. preferred) way to do handle URLs is the first one. So you would have a URL conf:
(r'^category_check_view/(\d{4})$', 'proj.app.your_view'),
And a matching view:
def your_view(request, id):
obj = Obj.objects.get(id=id)
# ...
However, if you insist on passing the param via GET you would just do:
(r'^category_check_view$', 'proj.app.your_view'),
And:
def your_view(request):
id = request.GET.get('item_id')
obj = Obj.objects.get(id=id)
# ...
You can't use get parameters in URL pattern. Use them in your view:
item_id = request.GET.get('item_id')
Related
Given a URL for example:
url(r'^article/(?P<article_id>\d+)/review/(?P<review_id>\d+)/rate/$', views.rate_reviewer,
name='review_rate_reviewer')
Is there a way in django that I could get a list of the Kwargs this URL required eg. ['article_id', 'review_id']?
Your view function signature should be:
def rate_reviewer(request, article_id, review_id):
#custom logic where you can use article_id and review_id
rate_article(article_id, review_id)
Other than that you could of course request url like:
http:localhost:8000/review_article?article_id=7&review_id=15....
and inside view function access these arguments with
def rate_reviewer(request):
article_id=request.GET.get("article_id",None)
review_id = request.GET.get("review_id", None)
You can access all arguments in GET request with request.GET (in POST request it's request.POST), and here you will get dictionary with all input parameters.
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.
I have a url that is meant to be accessed like
/people/raj/updates
/people/raj/updates?tag=food
But Django reverse URL resolver seems to have no provision to do tag=food, that is to detect it as an extra parameter and put in the query string.
How do I pass query parameters?
It depends on whether you are building the URL in the python code or in a template.
In python code (e.g. the view):
from django.http import QueryDict
query_dictionary = QueryDict('', mutable=True)
query_dictionary.update(
{
'tag': 'food'
}
)
url = '{base_url}?{querystring}'.format(
base_url=reverse(my.url.name),
querystring=query_dictionary.urlencode()
)
And in a template:
My Link
You caould also pass the QueryDict object from the view to the template and use that when building the URL in the template:
My Link
Django's reverse does not include GET or POST parameters. They are not part of the url.
You can of course always create the url by, for instance in a template, attaching the parameter as in:
{% url 'named_url' %}?tag=food
This way it gets attached anyway. Alternative is building an url regex that includes the possible tag, like:
url(r'^/people/raj/updates/(?P<tag>[a-zA-Z0-9]+/)?', yourview())
This way you can check for the kwarg tag in your view.
I want to define url pattern for the below url and read these parameters in views
http://example.com/user/account?id=USR1045&status=1
I tried
url(r'^user/account/(?P<id>\w+)/(?P<status>\d+)/$', useraccount),
In Views
request.GET ['id']
request.GET ['status']
but it is not working, please correct me.
django url patterns do not capture the query string:
The URLconf searches against the requested URL, as a normal Python
string. This does not include GET or POST parameters, or the domain
name.
For example, in a request to http://www.example.com/myapp/, the
URLconf will look for myapp/.
In a request to http://www.example.com/myapp/?page=3, the URLconf will
look for myapp/.
The URLconf doesn’t look at the request method. In other words, all
request methods – POST, GET, HEAD, etc. – will be routed to the same
function for the same URL.
So, with that in mind, your url pattern should be:
url(r'^user/account/$', useraccount),
In your useraccount method:
def useraccount(request):
user_id = request.GET.get('id')
status = request.GET.get('status')
if user_id and status:
# do stuff
else:
# user id or status were not in the querystring
# do other stuff
Querystring params and django urls pattern are not the same thing.
so, using django urls pattern:
your url:
http://example.com/user/account/USR1045/1
urls.py
url(r'^user/account/(?P<id>\w+)/(?P<status>\d+)/$', views.useraccount)
views.py
def useraccount(request, id, status):
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'])