2

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!!

Rose
  • 2,619
  • 4
  • 20
  • 27

3 Answers3

2

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.

Rohan
  • 52,392
  • 12
  • 90
  • 87
  • Thanks, that's exactly what the problem was. Thank you for noticing and pointing it out :) it works now! – Rose Jul 12 '16 at 17:00
2

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)
Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • 1
    Thank you so much! Such a dumb mistake I did there :) Thank you for pointing it out and giving tips on top of it :) I appreciate it very much. It works now! – Rose Jul 12 '16 at 16:59
1

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 }}
alioguzhan
  • 7,657
  • 10
  • 46
  • 67