How to set optional parameter in a django url? [duplicate] - django

This question already has answers here:
Django optional URL parameters
(7 answers)
Closed 4 months ago.
I have write down this code in a url
path('list/<str:name>', GetList.as_view(), name = "getList" )
my view.py
class BlogList(View):
def get(self,request, *args, **kwargs):
now i want to set name as optional parameter with list it show show all and with name i will implement query

There are multiple approaches to do this, One simple approach is to have multiple rules that matches your needs, all pointing to the same view.
urlpatterns = patterns('',
url(r'^project_config/$', views.foo),
url(r'^project_config/(?P<product>\w+)/$', views.foo),
url(r'^project_config/(?P<product>\w+)/(?P<project_id>\w+)/$', views.foo),
)
Also keep in mind that in your view you'll also need to set a default for the optional URL parameter, or you'll get an error:
def foo(request, optional_parameter=''):
# Your code goes here
For Django version > 2.0
Similar approach , but syntax
urlpatterns = [
path('project_config/',views.foo,name='project_config'),
path('project_config/<product>/',views.foo,name='project_config'),
path('project_config/<product>/<project_id>/',views.foo,name='project_config'),
]

Related

django restframwork Put and DELETE doesn't work

Get and post work pretty well for me .
but put and delete i use "U_repo_name" to look in table
i got the error message :
Page not found (404)
Request Method: PUT
Request URL: http://localhost:8000/gitapi/repo/authoo/
Using the URLconf defined in gitit.urls, Django tried these URL patterns, in this order:
admin/
gitapi/ [name='gitapi']
gitapi/ repo/
gitapi/ repo/str:U_repo_name
this is my model :
class UserRepos(models.Model):
U_repo_name =models.CharField( max_length=50)
this is my url :
urlpatterns = [
path('repo/',view=userreposapi),
path('repo/<str:U_repo_name>',view=userreposapi),
]
project urls :
urlpatterns = [
path('admin/', admin.site.urls),
path('gitapi/',include('gitapi.urls')),
]
this is my serializer :
class UserReposSerializer(serializers.ModelSerializer):
class Meta:
model = UserRepos
fields ='__all__'
and this is my views :
#csrf_exempt
def userreposapi(request,id=0):
if request.method=='GET':
userrepos = UserRepos.objects.all()
userreposserializer = UserReposSerializer(userrepos , many=True)
return JsonResponse(userreposserializer.data , safe=False)
elif request.method=='POST':
userrepos_data=JSONParser().parse(request)
userreposerializer = UserReposSerializer(data=userrepos_data)
if userreposerializer.is_valid():
userreposerializer.save()
return JsonResponse("added successfully!!",safe=False)
return JsonResponse("failed to add",safe=False)
elif request.method=='Put':
userrepos_data=JSONParser().parse(request)
userrepos = UserRepos.objects.get(U_repo_name=userrepos_data['U_repo_name'])
userreposserializer=UserReposSerializer(userrepos,data=userrepos_data)
if userreposserializer.is_valid():
userreposserializer.save()
return JsonResponse("updated successfully", safe=False)
return JsonResponse("failed to update",safe=False)
elif request.method=='DELETE':
userrepos = UserRepos.objects.all()
userrepos.delete()
return JsonResponse("deleted",safe=False)
Hi! I see a few issues with your code that might be causing this problem.
request.method is always full capitalized, so you should use the string 'PUT' instead of 'Put' on this line:
elif request.method=='Put':
You are adding a trailing slash to your route when trying to access it (/gitapi/repo/authoo/), but the pattern set in urlpatterns doesn't have this trailing slash:
path('repo/<str:U_repo_name>',view=userreposapi),
You can use re_path() instead of path() to set a regex URL pattern that works whether you add a trailing slash or not:
re_path(r'repo/(?P<U_repo_name>\w+)/?', view=userreposapi),
(?P<U_repo_name>\w+) creates a named group called U_repo_name that matches any word character ([a-zA-Z0-9_]) from one to more times. /? matches a single optional /.
Your route 'repo/<str:U_repo_name>' captures a string in the variable U_repo_name. This variable is provided to the view userreposapi() as a keyword argument, but the view currently only accepts the id kwarg. You should either add the U_repo_name kwarg as an optional argument or make the view accept other keyword arguments with **kwargs:
# Both are valid:
def userreposapi(request, id=0, U_repo_name=None):
...
def userreposapi(request, id=0, **kwargs):
...
Fixing these 3 issues should make the route work.
I think the trailing slash in the url is the problem. I should be not there.
http://localhost:8000/gitapi/repo/authoo # here I removed the trailing slash.

How to perform a query by using URL with question mark in Django?

It seems like the original URL querying function has been removed from Django 3.1. Does anyone know how to do it with a new package?
The url.py:
urlpatterns = [
re_path(r'^portfolio/(?P<title>[\w-]+)/$' , BlogApp_View.displayPortfolio, name='displayPortfolio'),
path('portfolio/', BlogApp_View.selectPortfolio, name='selectPortfolio'),]
The view.py
def displayPortfolio(request):
title = request.GET.get('title')
portfolio = Article.objects.filter(articleType__name__contains = "Portfolio", title=title)
print(title)
DICT = {}
return render(request, 'Article/', DICT)
The problem is now if I visit http://127.0.0.1:8000/Blog/portfolio/?title=A_UAV_Positioning_Approach_Using_LoRa/, it will skip the re_path shows in url.py.
Instead, it goes to the path one.
I have tried str:title method but that is actually not what I want. I prefer using the question mark pattern to finish the query.
The part after the questionmark is the querystring [wiki] and is not part of the path. This thus means that regardless what patterns you write, you can not distinguish on this, since the path patterns, regardless whether it is a path or re_path, are never matched against a URL with a query string.
You thus should write a single view, and inspect the request.GET query dict (which is a dictionary-like representation of the query string and see if it contains a value for title.
Your urlpatterns thus look like:
urlpatterns = [
path('portfolio/', BlogApp_View.selectPortfolio, name='selectPortfolio'),
]
and in the view, you can see if it contains a title:
def selectPortfolio(request):
if 'title' in request.GET:
# contains a ?title=…
title = request.GET.get('title')
portfolio = Article.objects.filter(
articleType__name__contains='Portfolio',
title=title
)
data = {'portfolio': portfolio}
return render(request, 'some_template.html', data)
else:
# contains no ?title=…
# …
return …

Properly storing values passed in URL in Django

I have the following URL:
http://localhost:8000/store/add/?points=5
I want to extract the number of points from my URL.
In my views.py, I have:
points = request.GET.get('points',0)
The problem is that it never finds points, so it uses the default of 0.
Any insight into what I'm doing wrong?
My urls.py
from django.conf.urls.defaults import *
from store.models import Part, Category, UniPart, LibraryRequest
from django.views.generic.list_detail import object_list
from voting.views import vote_on_object
urlpatterns=patterns('',
#/store/
url(r'^$','store.views.all_models',name="all_models"),
#/integer/view_part
url(r'^(\d+)/view_part/$','store.views.view_part',name="view_part"),
url(r'^your_models/$','store.views.your_models',name="your_models"),#/your_model
url(r'^user_models/(?P<username>\w+)/$','store.views.user_models',name="user_models"),
url(r'^add/(?P<points>\d+)/','store.views.add_model'),
Snipped from views.py:
def add_model(request, points=None):
print points
Well, your urls.py says that you should use following url /store/add/5, and in your views.py you need to have view
def add_model(request, points=None):
print points
If you want points as a GET parameter change your urls.py as following:
url(r'^add$','store.views.add_model', name='add_model'),
And then you can pass points as /store/add?points=5 and extract it from the URL as
points = request.GET.get('points')
UPDATE
Also in a future to avoid such problems I suggest you to add name parameter to your routes in urls.py (see above) and use reverse in your views (ex. reverse('add_model', kwargs={'points': 5}) and url in your templates (ex. {% url 'add_model' 5 %})
In that case all urls in your application will be generated automatically based on routes in your urls.py files.
Use the following code:
points = request.GET.get('points')
If you are passing more than one variable it can be done in two ways:
METHOD 1:
In your urls.py.
(r'^store/add1/?integer=(?P<category>\d+)/?string=(?P<keyword>\w+)$', 'view_function_name'),
You can get the above values in your views using the following:
def function_name(request):
int_value = request.GET.get('integer')
str_value = reuest.GET.get('string')
And you can also use the pattern given below:
METHOD 2:
In your urls.py.
urlpatterns = patterns('model_name.views',
(r'^store/add1/(?P<integer>\d+)/(?P<string>\w+)/', 'function_name')
)
In your views.py:
def function_name(request, integer= None, string = None):
print integer
print string
#Do whatever you wish with this value
The second method will be more easy for you.

Problem using generic views in django

I'm currently working with django generic views and I have a problem I can't figure out.
When using delete_object I get a TypeError exception:
delete_object() takes at least 3 non-keyword arguments (2 given)
Here is the code (I have ommited docstrings and imports):
views.py
def delete_issue(request, issue_id):
return delete_object(request,
model = Issue,
object_id = issue_id,
template_name = 'issues/delete.html',
template_object_name = 'issue')
urls.py
urlpatterns = patterns('issues.views',
(r'(?P<issue_id>\d+)/delete/$', 'delete_issue'),
)
The other generic views (object_list, create_object, etc.) work fine with those parameters. Another problem I have is when using the create_object() function, it says something about a CSRF mechanism, what is that?
You need to provide post_delete_redirect, this means url, where user should be redirected after object is deleted. You can find this in view signature:
def delete_object(request, model, post_delete_redirect, object_id=None,
slug=None, slug_field='slug', template_name=None,
template_loader=loader, extra_context=None, login_required=False,
context_processors=None, template_object_name='object'):

TypeError when passing dictionary arguments to a view through urls.py

I'm trying to pass keyword arguments to a Django view using a dictionary, but I keep running into a TypeError when I try to access the URL (The error is: "add_business_contact() got an unexpected keyword argument 'info_models'"). The code is:
urlpatterns = patterns('business.views',
# ...
url(r'^(?P<business_id>[\w\._-]+)/edit_contact$', 'add_business_contact', {
'info_models': [Email, PhoneNumber, URL] }, name='business_contact'),
# ...
)
and the corresponding view:
#login_required
def add_business_contact(request, business_id, *args, **kwargs):
# ...
info_models = kwargs.pop('info_models', None)
# ....
If I remove the dictionary argument from the url() function, it happily reaches and runs the view (albeit incorrectly since it doesn't have that argument). Any ideas as to why it's doing this? I'm following an example from the Django Book ( http://djangobook.com/en/2.0/chapter08/ ) if that helps at all.
Wooops. A bit embarassing but I copy/pasted the function while working on it and didn't rename the original. It's working now as expected...