1
votes

I have a model:

class Tour(models.Model):

    owner_id = models.ForeignKey(User)
    name = models.CharField(max_length=50)
    location = models.ManyToManyField(Location)
    subscribers = models.ManyToManyField(User, related_name="sub")
    tour_date = models.DateField(null=True)
    description = models.CharField(max_length=300, null=True)

And a template that includes this form:

 <form method="post" action="/mytours/">
 {% csrf_token %}
 <input name="name" value="{{ name }}" class="pull-left" type="text" placeholder="Type the tour name... "></br>
 <input name="tour_date" value="{{ tour_date }}" type="text" id="datepicker" placeholder="Pick a tour date..."/>
  <button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
  <button type="submit" class="btn btn-primary">Save</button>
</form>

And in my views I am trying to add to my database what is filled in the form:

if request.method == 'POST':
        location = Location.objects.get(id=1)
        name = request.POST.get('name', '')
        tour_date = request.POST.get('tour_date', '')
        tour = Tour()
        tour.owner_id = user.pk
        tour.name = name
        tour.tour_date = tour_date
        tour.location = location
        tour.save()
        c = {'name':name, 'tour_date':tour_date, 'tour':tour}
        c.update(csrf(request))
        return render_to_response("myTours.html", c)

I am new in django and I don't know where is the problem.

4

4 Answers

4
votes

You're misunderstanding what to do with the CSRF token. You're creating it on POST, but the point is to create it for the original display of the form on the GET request. It is checked by the middleware on POST, so you don't need to add it there.

You should use the render call as recommended by surfeurX, but on the call that displays the form in the first place.

1
votes

What I do when I implement forms in django is writing a form class and creating an instance of it in the view. Then pass the instance to the template.

# form class eg. in models.py
from django import forms

class TourForm(forms.Form):
    name = forms.CharField(max_length=50)

# in the view
if request.method == 'POST':
    form = TourForm(request.POST)
    if form.is_valid():
        # do your stuff here with form data
else:
    form = TourForm() # An unbound form

return render(request, 'myTours.html', {
    'form': form,
})

in your template you can display the generated form like this:

<form action="/mytours/" method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Save" class="btn btn-primary" />
</form>

for further information just look inside the official django forms documentation

0
votes

You probably need to add django.middleware.csrf.CsrfViewMiddleware to MIDDLEWARE_CLASSES and add a RequestContext to your response:

return render_to_response("myTours.html", c, context_instance=RequestContext(request))

https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/

0
votes

How do you render your template ??? I think your csrf_token doesn't print any hidden input, add "request" in your template context like:

return render(request, "template.html", {"var": var})

https://docs.djangoproject.com/en/dev/topics/http/shortcuts/#render