Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django ModelForm not saving data

Tags:

python

django

I've tried solutions from the following posts:

Saving data from ModelForm : Didn't work

ModelForm data not saving django : Didn't work.

I'm trying to save data from a ModelForm into the model.

models.py:

class Testimonials(models.Model):
    name = models.CharField(max_length=128)
    credentials = models.CharField(max_length=128)
    test = models.CharField(max_length=2000)
    id = models.AutoField(primary_key=True)
    NO = 'NO'
    YES = 'YES'
    APPROVAL = ((NO, 'no'), (YES, 'yes'))
    verified = models.CharField(choices=APPROVAL, default=NO, max_length=3) #Field for making sure only verified testimonials are displayed

    def __unicode__(self):
        return self.id

forms.py:

class TestimonialForm(forms.ModelForm):
    name = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control input-area', 'placeholder': 'Enter your name'}), required=True)
    credentials = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control input-area', 'placeholder': 'Enter your designation'}), required=True)
    test = forms.CharField(widget=forms.Textarea(attrs={'class': 'form-control test-form-area', 'placeholder': 'Testimonial', 'rows': '5'}), required=True)
    verified = forms.ChoiceField(widget=forms.HiddenInput())

    class Meta:
        model = Testimonials  

views.py

def add_testimonial(request):
    context = RequestContext(request)
    if request.method == 'POST':
        form = TestimonialForm(request.POST)

        if form.is_valid():
            form.save(commit=True)
            return HttpResponseRedirect('/testimonials/thanks/')
        else:
            print form.errors

    else:
        form = TestimonialForm()

    return render_to_response('templates/add_testimonial.html', {'form': form}, context)

Template:

<form id="testimonial_form" method="POST" action="/testimonials/thanks/">
    {% csrf_token %}
    {% for hidden in form.hidden_fields %}
        {{ hidden }}
    {% endfor %}
    {% for field in form.visible_fields %}
        {{ field.help_text}}
        {{ field }}
    {% endfor %}
    <input type="submit" name="submit" value="Add testimonial" class="btn btn-info test-button"/>
</form>

EDIT:

urls.py

url(r'^testimonials/all/', views.testimonials, name='testimonial'),
url(r'^testimonials/thanks/', views.testimonials_thanks, name='testimonial_thanks'),
url(r'^add_testimonial', views.add_testimonial, name='add_testimonial'),

However, on redirect, it doesn't save the form into the model which I'm checking from both PHPMyAdmin (using a MySQLdb) and the Django Admin panel. Any idea why?

like image 777
Newtt Avatar asked May 15 '14 21:05

Newtt


1 Answers

You are POSTing to /testimonials/thanks/ which should be changed to your add_testimonial route to have your view handle the POST. So, the solution is to change the action value in your template's form tag.

If you can post the relevant code from your urls.py I can provide a more specific answer as to what the value of the action attribute should be.

Update

The redirect will happen in your view when a valid form is POSTed. Change your template's action attribute value to:

<form id="testimonial_form" method="POST" action="{% url 'add_testimonial' %}">

In your view:

if form.is_valid():
    form.save()
    return HttpResponseRedirect(reverse('testimonial_thanks'))

And make sure you include the following import in your view:

from django.core.urlresolvers import reverse

Update 2

Display your form errors in your template:

<form id="testimonial_form" method="POST" action="{% url 'add_testimonial' %}">
    {% csrf_token %}
    {% if form.non_field_errors %}
        <div class="form-group text-error">
            {{ form.non_field_errors }}
        </div>
    {% endif %}

    {% for hidden in form.hidden_fields %}
        {{ hidden }}
    {% endfor %}
    {% for field in form.visible_fields %}
        {{ field.help_text}}
        {{ field }}
        {% if field.errors %}
            <span>{{ field.errors|striptags }}</span>
        {% endif %}
    {% endfor %}
    <input type="submit" name="submit" value="Add testimonial" class="btn btn-info test-button"/>
</form>

Update 3

Now that you can see your form errors, you will need to provide your default value to the hidden field, and there's no need to make it a ChoiceField if the user has no choice (it's hidden!). So change the verified form field to:

verified = forms.CharField(widget=forms.HiddenInput(), initial='no')

Also, it would be a good idea to verify the value in your view since even though the field is hidden, an enterprising, evil user can still POST other values.

like image 97
Fiver Avatar answered Nov 05 '22 07:11

Fiver