How would I handle another POST request on my site
Hello in my login site I have a form that sends a POST request on submit.
this is how I handle the forms POST request in my view
def SignUp(request):
if request.method == 'POST':
stuff goes here
else:
form = SignUpForm()
return render(request, "index.html", {"form": form})
now in my javascript i want to add another POST request that'll check if the current username within a certain is already taken. I made it and sent the POST to my current view where both this POST request will be handled along with the form POST request. what ends up happening is that SignUp() keeps handling both the POST requests. How do I handle two POST requests in one view? Is there a better way to do all of this? (i would preferably want to stay on this url)
tried to read about any way to differentiate between POST requests but found nothing. (i started learning django just a few days ago and im completely lost trying to make this work)
You need to use another route. URI's are used to create hierarchical addresses for endpoints where functionality is handled. Since you want to use another POST, you need to have another route for it to go to. Here is an example of a routing structure (restful) for a web API for data and users.
Handle data actions
- get data or create new data
/api/data
- GET
- POST
- get a piece of data, update it, delete it
/api/data/:id
-GET
-PUT
-DELETE
Handle user actions
/api/user
-GET
-POST
/api/user/:id
-GET
-PUT
-DELETE
Notice there are different HTTP Verbs (GET,PUT,POST, DELETE) handled at each endoint, but never twice at an endpoint.
I think Flask is a better place to start off with some of these concepts. Here is a blog article about Flask and routing. https://auth0.com/blog/developing-restful-apis-with-python-and-flask/
The most usual way would be to use different URL paths for each POST request. This means having one URL for the sign-up form submission and another URL for the username availability check. (I recommend to inspect similar web application behaviors by using Developer tools -> Network tab, while they are doing similar thing)
Best practice and recommended way: Using different URL for username_check
:
In urls.py
from django.urls import path
from .views import SignUp, check_username
urlpatterns = [
path('signup/', SignUp, name='signup'),
path('check_username/', check_username, name='check_username'),
]
In views.py
def check_username(request):
if request.method == 'POST':
# Handle the username check
...
If you still want to do it in the same URL, not best practice but it is possible by checking the request.POST content. For example, if the username check only sends the username, while the sign-up sends other fields like email and password, you could do:
def SignUp(request):
if request.method == 'POST':
if 'username' in request.POST and 'email' not in request.POST:
# This must be the username check
...
else:
# This must be the sign-up form
...
else:
form = SignUpForm()
return render(request, "index.html", {"form": form})
Lastly, I recommend to research about implenting API views, REST structure and Django Rest Framework as a learning path for this type of "background" features.
If you need to know a username is already taken or not you can simply do it with overriding clean method of your form:
class SignUpForm(UserCreationForm):
...
def clean_username(self):
username = self.cleaned_data['uesrname']
if User.objects.filter(username=username).exists():
raise ValidationError("Email already exists")
return email
check this > https://docs.djangoproject.com/en/4.2/ref/forms/validation/
btw the best way to keep your field unique is to put unique=True
in your model field. I hope it helped.
You can simply set additional parameters in the payload to distinguish between post requests.
For example in your views.py you can set an additional parameter signup as part of your payload:
if request.method == "POST":
signup = request.POST.get('signup', 'normal'):
if signup == 'normal':
# implement normal signup logic..
else:
# implement custom logic
In your template make sure to add signup
as an attribute of the form with a default value of normal
in this case. Include it as well in any javascript post calls you make to the view. You can then implement whatever else if conditions in your view.