Reputation: 2819
I am new to django and trying to show a form in an html file and I don't see the fields when I get to this particular page on my browser. Anybody has an idea why?
Here is the html file : In which I can see everything but the form showing up add_device.html
{% extends 'layout/layout1.html' %}
{% block content %}
<form action = "userprofile/" method = "post">
{% csrf_token %}
{{ form }}
<input type = "submit" value = "Submit"/>
</form>
{% endblock %}
forms.py
from django import forms
from models import UserProfile
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('deviceNb',)
models.py
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User)
deviceNb = models.CharField(max_length = 100)
User.profile = property(lambda u : UserProfile.objects.get_or_create(user = u)[0])
views.py
def user_profile(request):
if request.method == 'POST':
#we want to populate the form with the original instance of the profile model and insert POST info on top of it
form = UserProfileForm(request.POST, instance=request.user.profile)
if form.is_valid:
form.save()
#to go back to check that the info has changed
return HttpResponseRedirect('/accounts/loggedin')
else:
#this is the preferred way to get a users info, it is stored that way
user = request.user
profile = user.profile
#if we have a user that has already selected info, it will pass in this info
form = UserProfileForm(instance=profile)
args = {}
args.update(csrf(request))
args['form'] = form
print(form)
return render_to_response('profile.html',args)
I am pretty sure my url file is ok, since I get to the right urls, my problem is really the form fields not showing up.
Thank you so much!!
Upvotes: 2
Views: 12813
Reputation: 7917
You should handle GET
request, too. Try this in your view:
def user_profile(request):
form = UserProfileForm()
if request.method == 'GET':
# handle GET request here
form = UserProfileForm(instance=request.user.profile)
elif request.method == 'POST':
#we want to populate the form with the original instance of the profile model and insert POST info on top of it
form = UserProfileForm(request.POST, instance=request.user.profile)
if form.is_valid:
form.save()
#to go back to check that the info has changed
return HttpResponseRedirect('/accounts/loggedin')
args = {}
args['form'] = form
return render_to_response('profile.html',args)
And in your profile.html
, you can do something like this:
{{ form.as_p }}
Upvotes: 1
Reputation: 309089
The indentation of your view is incorrect. The else
block belongs with the if request.method == 'POST'
statement, and handles GET requests.
You also need to fix the indentation at the end of the method, so that you return a response for get and post requests. It's better to use render
instead of the obsolete render_to_response
. This simplifies your code, because you don't need to call args.update(csrf(request))
anymore.
from django.shortcuts import render
def user_profile(request):
if request.method == 'POST':
#we want to populate the form with the original instance of the profile model and insert POST info on top of it
form = UserProfileForm(request.POST, instance=request.user.profile)
if form.is_valid:
form.save()
#to go back to check that the info has changed
return HttpResponseRedirect('/accounts/loggedin')
else:
#this is the preferred way to get a users info, it is stored that way
user = request.user
profile = user.profile
#if we have a user that has already selected info, it will pass in this info
form = UserProfileForm(instance=profile)
args = {}
args['form'] = form
return render(request, 'profile.html', args)
Upvotes: 2
Reputation: 53386
You are not handling GET
request in your view. Update code of the view as
def user_profile(request):
if request.method == 'POST':
# your existing code
# .....
else : #when its get request
form = UserProfileForm(instance=request.user.profile)
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('profile.html',args)
This is a sample code, it can be improved.
Upvotes: 2