Django Form Submission button not working - python

So, I am following code4startup tutorial on how to create a similar to Ubereats app. Right now, I am trying to register a new Restaurant & restaurant owner to the database. I am using a form from Django to handle all the datafields.
Everything works fine until I hit the "sign-up" button. My code is SUPPOSED TO POST all the data from the form into the database, then automatically log-in the newly created restaurant owner into the restaurants page. HOWEVER, when i press the sign-up button, nothing happens and instead the sign-up page is reloaded.
How can i solve this issue? The tutorial I'm following is from 2017 i think so the django version the author uses is old.
Below are some snippets from my code:
SIGN-UP HTML (BUTTON ONLY, FORM WORKS OK):
<form method="POST" enctype="multipart/form-data" >
{% csrf_token %}
{{ user_form }}
{{ restaurant_form }}
<button type="submit">Sign Up</button>
VIEWS.py
def restaurant_home(request):
return render(request, 'restaurant/home.html', {})
def restaurant_sign_up(request):
user_form = UserForm()
restaurant_form = RestaurantForm()
#when submitting data:
if request == "POST":
user_form = UserForm(request.POST)
restaurant_form = RestaurantForm(request.POST, request.FILES)
if user_form.is_valid() and restaurant_form.is_valid():
new_user = User.objects.create_user(**user_form.cleaned_data)
new_restaurant = restaurant_form.save(commit=False)
new_restaurant.user = new_user
new_restaurant.save()
login(request, authenticate(
username = user.form.cleaned_data["username"],
password = user.form.cleaned_data["password"]
))
return redirect(restaurant_home)
return render(request, 'restaurant/sign_up.html', {
"user_form": user_form,
"restaurant_form": restaurant_form
})

I should be request.method in
if request.method == "POST":
Doc: HttpRequest.method

add the action attribute in the form tag to direct to the desired page
<form action=“/home“ method=“POST” ...>

Related

Django Form Not Saving the Data

I've imported this from django.contrib.auth.forms import UserCreationForm
used csrf_token in the form but still when I hit submit the page reloads but doesn't save the data to database.
def signup(req):
if req.method == 'POST':
form = UserCreationForm(req.POST)
if form.is_valid():
form.save()
form = UserCreationForm()
reg_con={
'regform': form
}
return render(req, 'signup.html', reg_con)
form
<form action="." method="POST">
{% csrf_token %}
{{ regform.as_ul }}
<input type="submit" value="Sign Up">
</form>
This is normally because something is wrong with your form the problem is however that you each time construct a new form, and you thus can not see what went wrong. You should only create a new form in case it is a GET request, so:
def signup(req):
if req.method == 'POST':
form = UserCreationForm(req.POST)
if form.is_valid():
form.save()
else:
form = UserCreationForm()
reg_con={
'regform': form
}
return render(req, 'signup.html', reg_con)
Try removing the action attribute from your form tag. Also don't forget to redirect after calling form.save()

Django register form POST data not validated by view in production?

For some reason the POST data from my Django app's user sign up form doesn't get validated by the signup view. It works perfectly in development on my local machine, but not in production. I have also inspected the web content and the POST data gets created but the page just reloads an empty form. What could cause this?
signup.html
<form method="POST" autocomplete="off" novalidate>
{% csrf_token %}
{% cache 86400 signup %}
...
<button type="submit">Sign up</button>
{% endcache %}
</form>
views.py
def signup_view(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False
user.save()
return redirect('home')
else:
form = UserRegisterForm()
context = {
'title': 'Sign up',
'form': form,
}
return render(request, 'users/signup.html', context)
Found it! The template caching was causing the form to render without the POST content, making it seem as if no validation is happening.

Passing Dropdown Value To URL in Django

I am rendering a dropdown which displays a list of integers. This is the only field in the form/view. Once that form is submitted, the integer selected should be passed to the URL of the next view which is rendered on submission of the previous form.
I am getting a 404 when I attempt this.
Here is what I am currently trying:
forms.py
#this is the dropdown field
class ManifestDropDown(forms.Form):
reference = forms.ModelChoiceField(queryset=Orders.objects.values_list('reference', flat=True).distinct(),
empty_label=None)
views.py
#this is the view where the dropdown is submitted
def manifest_references(request):
if request.method == 'POST':
form = ManifestDropDown(request.POST)
if form.is_valid():
reference_id = form.cleaned_data.get('reference')
form.save()
return render('manifest', reference_id=reference_id)
query_results = Orders.objects.all()
reference_list = ManifestDropDown()
context = {
'query_results': query_results,
'reference_list': reference_list,
}
return render(request, 'manifest_references.html', context)
#this is the view where the value should be displayed in the url
def manifest(request, reference_id):
form = CreateManifestForm(request.POST)
if request.method == "POST":
....
data = Manifests.objects.all().filter(reference__reference=reference_id)
form = CreateManifestForm(initial={
'reference': Orders.objects.get(reference=reference_id),
})
total_cases = Manifests.objects.filter(reference__reference=reference_id).aggregate(Sum('cases'))
context = {
'reference_id': reference_id,
'form': form,
'data': data,
'total_cases': total_cases['cases__sum'],
}
return render(request, 'manifest_readonly.html', context)
urls.py
#url which displays the manifest view above
url(r'^manifest/(?P<reference_id>\d+)/$', manifest, name='manifest'),
url(r'^references_manifests', manifest_references, name='references_manifests'),
manifest_references.html
<div class="container">
<br>
<br>
<br>
<form method="POST" action="references_manifests">
{% csrf_token %}
{{ reference_list }}
<button type="submit" class="btn btn-primary" name="button">Create Proforma</button>
</form>
</div>
To dynamically change the URL that you're actually submitting to, you would need to use JavaScript.
But an alternative is to submit back to the manifest_references view, then redirect from there to manifest. (Note, you should always be redirecting, not rendering, after a successful submission anyway. And no need to call form.save(), this isn't a modelform so there is nothing to save.)
def manifest_references(request):
if request.method == 'POST':
form = ManifestDropDown(request.POST)
if form.is_valid():
reference_id = form.cleaned_data.get('reference')
return redirect('manifest', reference_id=reference_id)
You can do two things:
Call the manifest view directly.
Redirect the user to the manifest page.
The first one should be done like this:
if form.is_valid():
reference_id = form.cleaned_data.get('reference')
form.save()
return manifest(request, reference_id)
The second one can be done like this:
if form.is_valid():
reference_id = form.cleaned_data.get('reference')
form.save()
return HttpResponseRedirect(reverse('manifest', reference_id = reference_id))
It doesn't really matter which one you do, although I would recomment redirecting the user to the correct page, because then a refresh will not resend the form the user has entered.

django form view show error or not

I'm making a little personal project using Django framework and I get one question while making login view with django form.
I was struggled to show form error messages in my template, and I found a cause in my view.
This is view that showing error message
def login_view(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
form.login(request)
return redirect('/')
else:
form = LoginForm()
context = {
'form': form,
}
return render(request, 'member/login.html', context=context)
another view that dosen't showing error message
def login_view(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
form.login(request)
return redirect('/')
form = LoginForm()
context = {
'form': form,
}
return render(request, 'member/login.html', context=context)
and this is my template
<form action="{% url 'login' %}" method="post">
{% csrf_token %}
{{ form.username}}
{{ form.password }}
{{ form.non_field_errors }}
<button id="login-btn" class="btn btn-default" type="submit">login</button>
The difference is just using elsephrase or not in view.
I think whether using elsephrase or not, there two views have logically same result... I don't understand difference of those two views.
Is there any clue to understand the differece of those two views?..
Thanks
You're overwriting the POST form by defining the form at the end. Load the blank form first
def login_view(request):
form = LoginForm()
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
form.login(request)
return redirect('/')
context = {
'form': form,
}
return render(request, 'member/login.html', context=context)

Form is not saving user data into database Django

Python noob here trying to learn something very simple.
I'm trying to create a basic form that takes some personal information from a user and saves it into a sqlite3 table with the username of the user as the primary key.
My models.py looks like this:
class userinfo(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key= True,
on_delete=models.CASCADE)
name = models.CharField(max_length = 200, blank = True)
email = models.EmailField(max_length= 300, default = 'Null')
phone = models.CharField(max_length= 10, default = 'Null')
def __unicode__(self):
return self.user
forms.py:
class NewList(forms.ModelForm):
class Meta:
model = userinfo
exclude = {'user'}
views.py
def newlist(request):
if request.method == 'POST':
form = NewList(request.POST)
if form.is_valid():
Event = form.save(commit = False)
Event.save()
return redirect('/home')
else:
form = NewList()
return render(request, 'home/newlist.html', {'form': form})
html:
{% load static %}
<form action="/home/" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
urls.py too, but I don't know how that would help:
urlpatterns = [
url(r'^newlist/$', views.newlist, name='newlist')
]
So when I go to the url, I see the form. I can then fill the form, but when I submit the form, the data doesn't go into the database.
What am I doing wrong here?
Thanks in advance!
I think all you need to do is just save the form if it's valid, probably also add the userinfo as an instance of the form. You are also exluding the user from the form and need to assign it manually.
def newlist(request):
if request.user.is_authenticated():
user = request.user
if request.method == 'POST':
form = NewList(request.POST, instance=user.userinfo)
if form.is_valid():
form.save(commit=false)
form.user = user
form.save()
return redirect('/home')
else:
form = NewList(instance=user.userinfo) # add this if you want it to automatically fill the form with the old data if there is any.
return render(request, 'home/newlist.html', {'form': form})
The rest look like it should work.Except you need to send the post URL back to newlist:
{% load static %}
<form action="/newlist/" method="POST">
{% csrf_token %}
{{ form.as_p }}
</form>
If users are assigned at the creation of the model the first time, you don't need the user save, but since this is saving a users data you want to make sure they are logged in anyway:
def newlist(request):
if request.user.is_authenticated():
user = request.user
if request.method == 'POST':
form = NewList(request.POST, instance=user.userinfo)
if form.is_valid():
form.save()
return redirect('/home')
else:
form = NewList(instance=user.userinfo) # add this if you want it to automatically fill the form with the old data if there is any.
return render(request, 'home/newlist.html', {'form': form})
The instance is the model it is either going to save to, or copying data from. In the: form = NewList(request.POST, instance=user.userinfo) part, it is taking the POST data from the form, and linking that to the specific model entry of user.userinfo, however, it will only save to the database when you call form.save().
The user.userinfo is just so you can get the correct form to save to, as userinfo is a onetoone model to user. Thus making it possible to get it with user.userinfo.
The form = NewList(instance=user.userinfo) part is where it takes the currently logged in user's userinfo and copies into the form before it is rendered, so the old userinfo data will be prefilled into the form in the html. That being if it got the correct userinfo model.

Categories