Passing string parameters not working in Django - python

view.py
when i test my api with post man ,postman indicate tha this urls do not exist(404 not found) any solution please
url postman:localhost:8000/photoByCategory/nature/
#api_view(['GET'])
#permission_classes((permissions.IsAuthenticated,))
def photo_by_categorie(request, category=False):
if request.method == 'GET':
if category:
photo_by_cat = Photo.objects.filter(category=category)
serializer = PhotoSerializer(photo_by_cat, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
urls.py
re_path(r'photoByCategory/(?:(?P<category>\d+)/)?$', views.photo_by_categorie, name='photo_by_categorie'),

Well, I guess the problem is with your regex
Try this
from django.urls import path, re_path
# Match string after drinks/ prefix
path('photoByCategory/<str:category>/',views.photo_by_categorie),
# Match one or more characters (non-digit regular expression) after drinks/ prefix
re_path(r'^photoByCategory/(?P<category>\D+)/',views.photo_by_categorie),
Here you can find the relevant information.
Note: I have ran first one myself and it works as intended

Related

return to function from another function

i have a table which include all users and two columns at the end (Edit,Delete) and i just enabled the delete column, the issue is when i click on the delete icon the record will be deleted but the url will stuck on the delete function even if i used return render(request,'getUsersInfo.html') which is get all records function
Model Name: Users
urls:
from django.urls import path
from django.conf.urls import url
from . import views
urlpatterns = [
path('signup.html',views.signup,name=''),
path('getUsersInfo.html',views.getAllUsers,name=''),
url(r'^deleteUser/(?P<fullname>\D+)/$',views.deleteUser, name='deleteUser'),
# this is how to call a function without parameters url(r'^deleteUser/$',views.deleteUser, name='deleteUser'),
in the same view i have 3 functions (singup "add user", getAllUsers "get all the records to the table,deleteUser)
views:
def getAllUsers(request):
print("getAllUsers")
thesearchValue = ''
if 'SearchValue' in request.GET:
thesearchValue = request.GET['SearchValue']
print(request.GET['SearchValue'])
allUsers = User.objects.filter(fullname__icontains=thesearchValue)#all()
# return render(request,'getUsersInfo.html',{'allUsers':allUsers})
return render(request,'getUsersInfo.html',{'allUsers':allUsers})
else:
print("Empty")
allUsers = User.objects.all()
return render(request,'getUsersInfo.html',{'allUsers':allUsers})
def deleteUser(request,fullname):
print('delete the user')
todelete = User.objects.filter(fullname=fullname)
todelete.delete()
return render(request,'getUsersInfo.html')
Notice that i used return render(request,'getUsersInfo.html') which should call getAllUsers(request): but the url stuck on http://127.0.0.1:8000/deleteUser/John/
Rendering the same template as another view does not mean that you will somehow call other views. A template is nothing more than a tool to specify how to convert context data to a string, that is passed as HTTP response. You can use the same template in multiple views, and a view can render multiple templates.
You can make use of redirect(..) [Django-doc] to return a HTTP redirect response (302):
from django.shortcuts import redirect
def deleteUser(request,fullname):
print('delete the user')
todelete = User.objects.filter(fullname=fullname)
todelete.delete()
return redirect(getAllUsers)
Note: A GET request is not supposed to have side-effects, hence removing
objects when a user makes a GET request, is not compliant with the HTTP
standard. Therefore it might be better to remove a User with a POST request.

Django pass empty parameter

I'm trying to pass an empty parameter to render a template but I can not achieve this I do not know if the problem is in urls.py or views, I really appreciate a hand.
Urls
url(r'^hola/(\b[a-z\.-]+)$', views.hola, name='hola'),
Views
def hola(request, varr = ''):
#val = val
pregunta = Datos_usuario_DB.objects.all().order_by('-id').filter(activo="1")[:15]
plantilla = {'': 'index.html', 'nosotros': 'nosotros.html'}
return render(request, plantilla['%s' % varr], {'pregunta': pregunta})
When I access to hola/ it says that the website does not exist.
If you want /hola/ to work, it's easy to add another URL pattern:
url(r'^hola/$', views.hola, name='hola'),
url(r'^hola/([a-z\.-]+)$', views.hola, name='hola'),
It's not clear to me why you have \b in the regex, so I removed it.
your urls is not contains hola/ entry, so It returns error.
If you want to call hola/, you need to add url in urls.py

Django HttpResponseRedirect, It returned None instead

Trying to make a form with Django and using a HttpResponseRedirect, I expected this should be fairly easy, however I seem to be doing something wrong.
I keep getting an error:
The view hotel.views.hotel_registration didn't return an HttpResponse object. It returned None instead.
In this case my guess would be that HttpResponseRedirect is not working properly, since, when I remove the if statement with the contents everything is working fine, except I can't submit a form.
I have 2 views:
def hotel_registration(request):
if request.method == 'POST':
form = HotelRegistrationForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('hotel:hotel_registered')
else:
form = HotelRegistrationForm()
return render(request, 'hotel/hotel-registration-form.html', {'form': form})
def hotel_registered(request):
pass
And in urls.py
url(r'hotel-registratie/', hotel.views.hotel_registration, name='registration'),
url(r'hotel-geregistreerd/', hotel.views.hotel_registered, name='registered'),
These are all the parameters I have used in HttpResponseRedirect:
HttpResponseRedirect('hotel:hotel_registered')
HttpResponseRedirect('hotel_registered')
HttpResponseRedirect('/hotel_registered/')
HttpResponseRedirect(hotel_registered)
And then I rust wanted to redirect back to root:
HttpResponseRedirect('/')
And using reverse:
HttpResponseRedirect(reverse(hotel_registration))
HttpResponseRedirect(reverse('hotel_registration'))
What would be the right way to do this?
According to the following urls.py that you posted :
url(r'hotel-registratie/', hotel.views.hotel_registration, name='registration'),
url(r'hotel-geregistreerd/', hotel.views.hotel_registered, name='registered'),
You should make the redirection using one of the following methods :
return HttpResponseRedirect('hotel-geregistreerd/')
or
return HttpResponseRedirect(reverse('registered'))
or simply
return redirect('registered')
When you use HttpResponseRedirect provide the path of the url, if you use reverse or redirect you can use the name that you defined in your urls.py.

Django Rest Framework #detail_route yields 404

I have a ViewSet like
class CustomerViewSet(ModelViewSet):
queryset = models.Customer.objects.all()
serializer_class = serializers.CustomerSerializer
filter_class = filters.CustomerFilterSet
#detail_route
def licenses(self, request, pk=None):
customer = self.get_object()
licenses = Item.objects.active().sold().for_customer(customer)
serializer = serializers.ItemSerializer(licenses, many=True)
return Response(serializer.data)
Strapped into urls.py with router.register(r'customers', views.CustomerViewSet)
i can GET /api/customers and GET /api/customers/1000, but GET /api/customers/1000/licenses is not found. It gives me 404. The flow never enters the licenses method.
I looked at similar questions here, but they used an incorrect signature, which I do not: def licenses(self, request, pk=None)
python 3.4.0
djangorestframework==3.2.3
EDIT: Once again, I find my answer less than a minute after asking... Apparantly, the decorater needs parenthesees like #detail_route(). I thought these were always optional by convention..?
For a post request you'll need to specify the method because the detail_route decorator will route get requests by default.
Like so: #detail_route(methods=['POST'])
By default, router adds trailing slash to the url. So, GET /api/customers/ would be working instead of GET /api/customers. If you don't want to use trailing slash you can pass trailing_slash = False to router initializer.
E.g.-
router = DefaultRouter(trailing_slash = False)
router.register(r'customers', views.CustomerViewSet)
If that does not works, then there is a problem with the way you are importing router urls into main urls.

How do you make a url that passes a parameter work in Django?

I'm working on registration logic and I can't seem to make the parameter pass in to work properly. The error I get is a 404 page not found. Previously, I also got a “The view didn't return an HttpResponse object" error. Any help is appreciated.
Here is my url from urls.py:
url(r'^accounts/confirm/(?P<activation_key>\d+)/$', 'mysite.views.confirm', name='confirm'),
This is my views.py:
def confirm(request, activation_key):
if request.user.is_authenticated():
HttpResponseRedirect('/home')
user = Hash.objects.filter(hash_key = activation_key)
if user:
user = Hash.objects.get(hash_key = activation_key)
user_obj = User.objects.get(username= user.username)
user_obj.is_active = True
user_obj.save()
HttpResponseRedirect('/home')
I send the url with a string that looks like:
"Click the link to activate your account http://www.example.com/accounts/confirm/%s" % (obj.username, activation_key)"
So the link looks like this:
http://www.example.com/accounts/confirm/4beo8d98fef1cd336a0f239jf4dc7fbe7bad8849a127d847f
You have two issues here:
Remove the trailing / from your pattern, or make it /? so it will be optional.
/d+ will only match digits, and your link also contains other characters. Try [a-z0-9]+ instead.
Complete pattern:
^accounts/confirm/(?P<activation_key>[a-z0-9]+)$
Remove / from end of your url:
url(r'^accounts/confirm/(?P<activation_key>\d+)$', 'mysite.views.confirm', name='confirm'),
or add / to end of your link:
http://www.example.com/accounts/confirm/4beo8d98fef1cd336a0f239jf4dc7fbe7bad8849a127d847f/

Categories