13

I am a real beginner in web development. The following code is failing at the is_valid() check. But I do not understand why: The form should get its data filled from the POST-data or not?

Model:

class Statement(models.Model):
    text = models.CharField(max_length=255)
    user = models.ForeignKey(User)
    time = models.DateField()
    views = models.IntegerField()

ModelForm:

class StatementForm(ModelForm):
    class Meta: 
        model = Statement
        widgets = {
                   'time':forms.HiddenInput(),
                   'user':forms.HiddenInput(), 
                   'views':forms.HiddenInput(), 
        }

View function:

def new(request):  
    if request.method == 'POST': # If the form has been submitted...
        form = StatementForm(request.POST) # A form bound to the POST data
        if form.is_valid():
            stmt = form.save()
            path = 'stmt/' + stmt.id
            return render_to_response(path, {'stmt': stmt})
    else:  
        c = {}
        c.update(csrf(request))
        loggedin_user = request.user 
        d = datetime.now()
        form = StatementForm(request.POST, initial={'time': d.strftime("%Y-%m-%d %H:%M:%S"), 'user':loggedin_user, 'views':0})
        return render_to_response('new_stmt.html', {'form': form, },context_instance=RequestContext(request))

I found similar topics and tried a lot. This is how i think it should work. I really need advice.

Kris van der Mast
  • 16,343
  • 8
  • 39
  • 61
JoeFox
  • 1,051
  • 1
  • 10
  • 23
  • 5
    Go to earlier questions that you've asked and accept the best answer (if these is one) for a particular question. You can do this by placing the check mark next to an answer. – Simeon Visser Jun 20 '12 at 10:02

2 Answers2

14

All fields of your model are required. So, form.is_valid() will be True, if all fields are filled with correct values and are not blanked. You have declared fields time, user, views as hidden fields. Are you sure, that you have filled them in your template form? Also, you may want to auto stamp field time = models.DateField(). Modify your model field like

time = models.DateField(auto_now=True)`. 

After this you don't have to fill it by yourself in template form.

Your view must return HttpResponse object in all cases. If your form is not valid, i.e. if form.is_valid() will return False, then no HttpResponse object will be returned by your view. This can be the source of your fail. Add else statement for if form.is_valid():

from django.http import Http404
def new(request):  
    if request.method == 'POST': # If the form has been submitted...
        form = StatementForm(request.POST) # A form bound to the POST data
        if form.is_valid():
            stmt = form.save()
            path = 'stmt/' + stmt.id
            return render_to_response(path, {'stmt': stmt})
        else:
            # Do something in case if form is not valid
            raise Http404 
    else: 
        # Your code without changes
Hadi
  • 5,328
  • 11
  • 46
  • 67
stalk
  • 11,934
  • 4
  • 36
  • 58
  • Thank you this is clearly an improvement of my code. For my database i need the date in this format: d.strftime("%Y-%m-%d %H:%M:%S"). Would it be possible to initialize the date in the model given a special format like mine? – JoeFox Jun 18 '12 at 05:38
  • 1
    When `auto_now` is used for `DateField`, the `datetime.date` object with current date is passed as value. And when you need to read the `DateField`, you can choose any format you like. Also, as far as i know, `DateField` will store only date, i.e. only this part `%Y-%m-%d`. If you need to store date and time, then you should use `DateTimeField`. Look [DateField](https://docs.djangoproject.com/en/dev/ref/models/fields/#datefield) and [DateTimeField](https://docs.djangoproject.com/en/dev/ref/models/fields/#datetimefield). – stalk Jun 18 '12 at 06:34
4

Change this line:

    form = StatementForm(request.POST, initial={'time': d.strftime("%Y-%m-%d %H:%M:%S"), 'user':loggedin_user, 'views':0})

For this:

    form = StatementForm(initial={'time': d.strftime("%Y-%m-%d %H:%M:%S"), 'user':loggedin_user, 'views':0})
Goin
  • 3,856
  • 26
  • 44
  • 4
    wait, what is the difference between the two? I mean, i can see the Request.POST is missing... but how does that help? – bharal Sep 26 '12 at 18:01
  • To answer @bharal - the `new()` method has a conditional. It starts with `if request.method == 'POST': process the data...` then there's an `else` (if the method isn't a `POST`, i.e. if it's a `GET`). If it's not a `POST` method, then why would you include `request.POST` (which wouldn't exist here, after the `else`)? – ron_g Mar 18 '19 at 15:16