Django Url pattern (add paramether), and view - django

There is urls.py pattern.
url(r'^notice/(?P<article>[0-9]\d+)/', web.views.notice),
Here is views.py
def notice(request, article):
data = article
return render(request, "notice.html")
However, web brower shows 404 Error.
If I remove add parameter, it is ok.
What I am wrong?
Intended result (Blog style, not get parameter)
/notice/1, /notice/2, ...

I think what is happening is that [0-9]\d+ is expecting at least a 2-digit number, one digit for the [0-9] and then one or more digits following that due to the \d+. I believe what you really want is just
url(r'^notice/(?P<article>\d+)$', 'web.views.notice')

I don't know why you use d???
url(r'^issue/(?P<issue_id>[0-9]+)$', views.issue, name='issue'),
url(r'^project/(?P<pk>.*)$', login_required(views.ProjectView.as_view()), name='project'),

Based on the question you asked, I am getting that you want to display the data on the template based on the parameter passed in the URL.Let me try to explain it step by step:
First lets say you have the following url:
url(r'^notice/(?P<article>\d+)$', views.notice,name="notice")
Now lets define the view for fetching the data from the model, based on the parameter in the URL, i am assuming you are passing the PK in the URL:
def notice(request, article):
data = YourModelName.objects.get(id=article)
//Passing back the result to the template
context={"article":data}
return render(request, "notice.html",context)
Now in your template you can access the data as such:
{{ article.field_name }}
Hope this helps you out!!!!

Related

How can I pass named arguments to a Django view method?

I have a view method with two additional parameters:
def foo(request, email, token):
...
And I need to use reverse to generate a URL:
...
url = urlresolvers.reverse(
'my_app.views.foo',
kwargs={ 'token': <token>, 'email': <email> })
Is my use of reverse reasonable/acceptable, and
What does the URL pattern for foo look like?
1 - Yes, as far as it goes, but of course it will fail without the urlpattern. You can use either args or kwargs, depending on your case. Here you can use args, as they are both required args from your view function.
2 - Here's a urlpattern to get you going, but the regex is only an example, as I don't know what your regex needs to be.
url(r'^/(?P<email>[-\w]+)/(?P<token>\d{1,2})/$', 'views.foo', name='foo'),
Named urls are a good pattern to get into the habit of doing. You can pass the name to the reverse function too:
url = urlresolvers.reverse(
'foo',
args=['<email>', '<token>']
Yes
It's up to you to write it in your URLconf.
You might want to have a look at Django docs
By your question, though, it's probably better if you run through the tutorial. The third part explains how to write down the URL scheme for your site.

Send data from template to a view django

In my application data about a entry is displayed detailing their information. You can navigate between the entries via a hyperlink.
So far the code:
{{park.name}}
Has been suffient in dealing with this. The id is captured in the urls.py and onto views.py
The problem I now face is to deal with my 'location' entry. Examples of locations are 'Europe, UK', 'USA, New York'.
I know that:
{{park.location}}
with:
url(r'^location/(?P<park_location>\d+)$', Location_Main),
won't work, due to the spaces and commas etc.
How would I resolve this?
I would also like the 'location' view and 'location' url to handle the location of a parent company say ()
Thanks in advance
Why not pass pass park.id and then in view get the park object and then get its location:
the url:
url(r'^location/(?P<park_id>\d+)$', Location_Main, name="park_location"),
the template:
{{park.location}}
the view:
def Location_Main(request, park_id):
park = get_object_or_404(Park, pk=park_id)
location = park.location
Alternatively send the location as GET parameter:
the url:
url(r'^location/$', Location_Main, name="park_location"),
the template:
{{park.location}}
the view:
def Location_Main(request):
location = request.GET.get('location')
url(r'^location/(?P<park_location>[a-zA-Z0-9_.-]+)/$', Location_Main),
You will need to remove punctuation and non-english characters from the location names before using them in the url. Alternatively you can remove them when you define park.location.
You can use urlencode template filter to escape the characters as
{{park.location}}
With reference to this question you may have to change the url pattern as
url(r'^location/(?P<park_location>[\w|\W]+)$', Location_Main)

In Django, how do I deal with an "or" in the url regex once I get to the view?

I'm just learning Django, and am getting stuck with some url logic. I'm trying to allow either a category name or id in the url:
...
url(r'^(?P<booze_q>\w+|\d+)/$','glasses.views.booze'),
...
And then in thew view, only deal with that result once. However, if the url is a string - in this case, Whiskey, I get an error for trying to pass a string where an int is expected. This is the closest I've gotten so far:
def booze(request, booze_q):
booze = get_object_or_404(Booze,Q(pk=booze_q)|Q(name=booze_q))
return render_to_response('booze/detail.html', {'booze': booze})
But this returns an error: invalid literal for int() with base 10: 'Whiskey'
I'm sure it's a pretty easy thing, but this is my first Django app, so any help would be appreciated.
tl;dr: End result, I'd like mysite.com/1/ or mysite.com/Whiskey/ to both call the glasses.views.booze view, and get the object with id=1 or name=Whiskey
This is a common scenario you'll encounter quite often, which is typically handled by resorting to multiple arguments and having views behave differently based on which of the view arguments are then present or not.
What you do is first define a URL pattern that uniquely matches each specific case and then let Django's URL resolver set the arguments accordingly based on which of the patterns was matched.
Here's an example with a class based view, that performs two different queries based on which of the two keyword arguments, booze_id or booze_name, is set:
url(r'^(?P<booze_id>\d+)/$', BoozeDetailView.as_view()),
url(r'^(?P<booze_name>\w+)/$', BoozeDetailView.as_view()),
class BoozeDetailView(DetailView):
model = Booze
def get_object(self):
booze_id = self.kwargs.get('booze_id', None)
booze_name = self.kwargs.get('booze_name', None)
if booze_id:
return self.model.objects.get(id=booze_id)
else:
return self.model.objects.get(name=booze_name)
You will always get a string, even if the string contains a number.
1) You should not have a parameter that could be either an id or something else. One day you will enter an item whose name is a number and your app will fail.
2) When querying for pk with a string django automatically tries to convert it into an integer. You'll have to handle the non-pk case before constructing that query.

Django: grabbing parameters

I'm having the hardest time with what should be super simple. I can't grab the passed parameters in django.
In the browser I type:
http://localhost:8000/mysite/getst/?term=hello
My url pattern is:
(r'^mysite/getst/$', 'tube.views.getsearchterms')
My View is
def getsearchterms(request):
my_term = some_way_to_get_term
return HttpResponse(my_term)
In this case it should return "hello". I am calling the view, but a blank value is returned to me. I've tried various forms of GET....
What should some_way_to_get_term be?
The get parameters can be accesses like any dictionary:
my_term = request.GET['term']
my_term = request.GET.get('term', 'my default term')
By using arbitrary arguments after ? and then catching them with request.GET['term'], you're missing the best features of Django urls module : a consistent URL scheme
If "term" is always present in this URL call it must be meaningful to your application,
so your url rule could look like :
(r'^mysite/getst/(?P<term>[a-z-.]+)/', 'tube.views.getsearchterms')
That means :
That you've got a more SEO-FRIENDLY AND stable URL scheme (no ?term=this&q=that inside)
That you can catch your argument easily in your view :
Like this
def getsearchterms(request,term):
#do wahtever you want with var term
print term

Capturing URL parameters in request.GET

I am currently defining regular expressions in order to capture parameters in a URL, as described in the tutorial. How do I access parameters from the URL as part the HttpRequest object?
My HttpRequest.GET currently returns an empty QueryDict object.
I'd like to learn how to do this without a library, so I can get to know Django better.
When a URL is like domain/search/?q=haha, you would use request.GET.get('q', '').
q is the parameter you want, and '' is the default value if q isn't found.
However, if you are instead just configuring your URLconf**, then your captures from the regex are passed to the function as arguments (or named arguments).
Such as:
(r'^user/(?P<username>\w{0,50})/$', views.profile_page,),
Then in your views.py you would have
def profile_page(request, username):
# Rest of the method
To clarify camflan's explanation, let's suppose you have
the rule url(regex=r'^user/(?P<username>\w{1,50})/$', view='views.profile_page')
an incoming request for http://domain/user/thaiyoshi/?message=Hi
The URL dispatcher rule will catch parts of the URL path (here "user/thaiyoshi/") and pass them to the view function along with the request object.
The query string (here message=Hi) is parsed and parameters are stored as a QueryDict in request.GET. No further matching or processing for HTTP GET parameters is done.
This view function would use both parts extracted from the URL path and a query parameter:
def profile_page(request, username=None):
user = User.objects.get(username=username)
message = request.GET.get('message')
As a side note, you'll find the request method (in this case "GET", and for submitted forms usually "POST") in request.method. In some cases, it's useful to check that it matches what you're expecting.
Update: When deciding whether to use the URL path or the query parameters for passing information, the following may help:
use the URL path for uniquely identifying resources, e.g. /blog/post/15/ (not /blog/posts/?id=15)
use query parameters for changing the way the resource is displayed, e.g. /blog/post/15/?show_comments=1 or /blog/posts/2008/?sort_by=date&direction=desc
to make human-friendly URLs, avoid using ID numbers and use e.g. dates, categories, and/or slugs: /blog/post/2008/09/30/django-urls/
Using GET
request.GET["id"]
Using POST
request.POST["id"]
Someone would wonder how to set path in file urls.py, such as
domain/search/?q=CA
so that we could invoke query.
The fact is that it is not necessary to set such a route in file urls.py. You need to set just the route in urls.py:
urlpatterns = [
path('domain/search/', views.CityListView.as_view()),
]
And when you input http://servername:port/domain/search/?q=CA. The query part '?q=CA' will be automatically reserved in the hash table which you can reference though
request.GET.get('q', None).
Here is an example (file views.py)
class CityListView(generics.ListAPIView):
serializer_class = CityNameSerializer
def get_queryset(self):
if self.request.method == 'GET':
queryset = City.objects.all()
state_name = self.request.GET.get('q', None)
if state_name is not None:
queryset = queryset.filter(state__name=state_name)
return queryset
In addition, when you write query string in the URL:
http://servername:port/domain/search/?q=CA
Do not wrap query string in quotes. For example,
http://servername:port/domain/search/?q="CA"
def some_view(request, *args, **kwargs):
if kwargs.get('q', None):
# Do something here ..
For situations where you only have the request object you can use request.parser_context['kwargs']['your_param']
You have two common ways to do that in case your URL looks like that:
https://domain/method/?a=x&b=y
Version 1:
If a specific key is mandatory you can use:
key_a = request.GET['a']
This will return a value of a if the key exists and an exception if not.
Version 2:
If your keys are optional:
request.GET.get('a')
You can try that without any argument and this will not crash.
So you can wrap it with try: except: and return HttpResponseBadRequest() in example.
This is a simple way to make your code less complex, without using special exceptions handling.
I would like to share a tip that may save you some time.
If you plan to use something like this in your urls.py file:
url(r'^(?P<username>\w+)/$', views.profile_page,),
Which basically means www.example.com/<username>. Be sure to place it at the end of your URL entries, because otherwise, it is prone to cause conflicts with the URL entries that follow below, i.e. accessing one of them will give you the nice error: User matching query does not exist.
I've just experienced it myself; hope it helps!
These queries are currently done in two ways. If you want to access the query parameters (GET) you can query the following:
http://myserver:port/resource/?status=1
request.query_params.get('status', None) => 1
If you want to access the parameters passed by POST, you need to access this way:
request.data.get('role', None)
Accessing the dictionary (QueryDict) with 'get()', you can set a default value. In the cases above, if 'status' or 'role' are not informed, the values ​​are None.
If you don't know the name of params and want to work with them all, you can use request.GET.keys() or dict(request.GET) functions
This is not exactly what you asked for, but this snippet is helpful for managing query_strings in templates.
If you only have access to the view object, then you can get the parameters defined in the URL path this way:
view.kwargs.get('url_param')
If you only have access to the request object, use the following:
request.resolver_match.kwargs.get('url_param')
Tested on Django 3.
views.py
from rest_framework.response import Response
def update_product(request, pk):
return Response({"pk":pk})
pk means primary_key.
urls.py
from products.views import update_product
from django.urls import path
urlpatterns = [
...,
path('update/products/<int:pk>', update_product)
]
You might as well check request.META dictionary to access many useful things like
PATH_INFO, QUERY_STRING
# for example
request.META['QUERY_STRING']
# or to avoid any exceptions provide a fallback
request.META.get('QUERY_STRING', False)
you said that it returns empty query dict
I think you need to tune your url to accept required or optional args or kwargs
Django got you all the power you need with regrex like:
url(r'^project_config/(?P<product>\w+)/$', views.foo),
more about this at django-optional-url-parameters
This is another alternate solution that can be implemented:
In the URL configuration:
urlpatterns = [path('runreport/<str:queryparams>', views.get)]
In the views:
list2 = queryparams.split("&")
url parameters may be captured by request.query_params
It seems more recommended to use request.query_params. For example,
When a URL is like domain/search/?q=haha, you would use request.query_params.get('q', None)
https://www.django-rest-framework.org/api-guide/requests/
"request.query_params is a more correctly named synonym for request.GET.
For clarity inside your code, we recommend using request.query_params instead of the Django's standard request.GET. Doing so will help keep your codebase more correct and obvious - any HTTP method type may include query parameters, not just GET requests."