Sebastian Smolorz
Sebastian Smolorz

Reputation: 507

Django 1.9 form.is_valid fails on ModelForm

My model form worked perfectly when I had two fields: title and file. I decided to add some additional fields to my model form and now I cannot get form.is_valid() to return true.

View

def upload_view(request):  
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        print request.POST
        print request.FILES
        if form.is_valid():
            print "Form valid"
            upload = form.save()
            path = change_name(upload)
            runscript.delay(upload.pk, (str(upload.author.id) + '_' + str(upload.id)), path, setting, permutations, biohel_runs, attributes)
            return render(request, 'upload/submitted.html', {'title': upload.title, 'link': 'job/' + str(upload.id)})
        else:
            form = UploadFileForm()
            return render(request, 'upload/upload_view.html', {'error': "Sorry, try submitting your form again", 'form': form})
    else:
        form = UploadFileForm()


    return render(request, 'upload/upload_view.html', {'form': form})

Template

{{ error }}
    {{ form.errors }}
    {% if form.non_field_errors or form.errors %}
        <div class="error-list-block">
            <p>
                Please correct the errors below - Ensure all required fields
                are completed.
            </p>
            <ul>
                {% for error in form.non_field_errors|add:form.errors %}
                    <li>{{ error }}</li>
                {% endfor %}
            </ul>
        </div>
    {% endif %}
    <form class="upload" method="post" action="../upload/" enctype="multipart/form-data">{% csrf_token %}
        <label for="{{ form.title.id_for_label }}">{{ form.title.label }}</label>
            {{ form.title }}
        <span style="margin:0 auto;"><label for="{{ form.file.id_for_label }}">{{ form.file.label }}</label>
        {{ form.file }}</span>

        <div style="margin:10px auto;">
            <label for="{{ form.setting.id_for_label }}">{{ form.setting.label }}</label>
                {{ form.setting }}
             <label for="{{ form.permutations.id_for_label }}">{{ form.permutations.label }}</label>
                {{ form.permutations }}
             <label for="{{ form.biohel_runs.id_for_label }}">{{ form.biohel_runs.label }}</label>
                {{ form.biohel_runs }}
             <label for="{{ form.attributes.id_for_label }}">{{ form.attributes.label }}</label>
                {{ form.attributes }}
        </div>

Model

class Upload(models.Model):
    SETTING = (
        ('1', '1'),
        ('2', '2'),
        ('3', '3'),
        ('4', '4'),
    )

    PERMUTATIONS = (
        ('10', '10'),
        ('50', '50'),
        ('100', '100'),
        ('200', '200'),
    )

    BIOHEL = (
        ('250', '250'),
        ('500', '500'),
        ('1000', '1000'),
        ('2500', '2500'),
    )

    ATTRIBUTES = (
        ('10', '10'),
        ('50', '50'),
        ('100', '100'),
        ('200', '200'),
    )
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
    title = models.CharField(max_length=20)
#TODO - change status to be a text field and merge with error
    status = models.BooleanField(default=False)
    error = models.BooleanField(default=False)
    submit_date = models.DateTimeField(
            default=timezone.now)
    start_date = models.DateTimeField(
            blank=True, null=True)
    finish_date = models.DateTimeField(
            blank=True, null=True)#TODO change to unique name
    file = models.FileField(upload_to='experiments', null=True)
    result = models.FileField(null=True)
    setting = models.PositiveSmallIntegerField(default=1, choices=SETTING)
    permutations = models.PositiveSmallIntegerField(default=10, choices=PERMUTATIONS)
    biohel_runs = models.PositiveSmallIntegerField(default=250, choices=BIOHEL)
    attributes = models.PositiveSmallIntegerField(default=10, choices=ATTRIBUTES)

Form

from django import forms

from .models import Upload

class UploadFileForm(forms.ModelForm):

    class Meta:
        model = Upload
        fields = ('title', 'file', 'setting', 'permutations', 'biohel_runs', 'attributes')

When I submit what should be a perfectly valid form, I can't get it to validate. None of the error handling in the template displays any errors. Here is the printout of the POST and FILE values. As you can see nothing is missing! To reiterate, it works when I only have the two fields: title and file.

<QueryDict: {u'title': [u'sadsda'], u'biohel_runs': [u'250'], u'permutations': [u'10'], u'setting': [u'1'], u'attributes': [u'10'], u'csrfmiddlewaretoken': [u'EntGKVQhYqjnxYTIh6v8135Ic3JHZPRw']}>
<MultiValueDict: {u'file': [<InMemoryUploadedFile: 1_652a60b7-ff84-4b9d-bac0-623417de3d9d.arff (application/octet-stream)>]}>

Thank you for taking the time to read my question

Upvotes: 1

Views: 716

Answers (1)

Sayse
Sayse

Reputation: 43300

In the else clause, you remove all references to any errors that your form actually produces by assigning a new instance of the form to your variable. so you need to remove this

else:
    form = UploadFileForm()  # Remove me!

Theres no other problem with your code, your form just isn't valid.


As it turns out you also have the 4 fields there as PositiveIntegerFields but their choices are all strings so either change the fields to a CharField or change the choice to be integer

(10, '10'),

etc.

Upvotes: 4

Related Questions