Plasma
Plasma

Reputation: 2449

Can't seem to exclude a field in a django form

I have a Django project in which I have a view subclassed from the Django CreateView class. This view is used to upload a file to the server, and uses an UploadedFile model which I have created. The UploadedFile also needs to be associated with a project, which is stored as a ForeignKey called project in the UploadedFile model.

The project id is passed in as part of the URL: (r'^projects/(?P<proj_key>\d+)/$', UploadedFileCreateView.as_view(), {}, 'upload-new')

Because project is not really a form field, I know I need to exclude it using a ModelForm; however, even after I have done so, django never enters the form_valid method (if I put a logging call in it, it will never be written to the log, though logging works fine). I'm guessing that the ForeignKey is the culprit because as far as I can tell it worked before I added that in. I don't understand why django doesn't consider the form to be valid even after I excluded project.

Here is my model definition:

class Project(models.Model):
    """This is a project that is owned by a user and contains many UploadedFiles."""
    name = models.CharField(max_length=200)

class UploadedFile(models.Model):
    """This represents a file that has been uploaded to the server."""
    STATE_UPLOADED = 0
    STATE_ANNOTATED = 1
    STATE_PROCESSING = 2
    STATE_PROCESSED = 4
    STATES = (
        (STATE_UPLOADED, "Uploaded"),
        (STATE_ANNOTATED, "Annotated"),
        (STATE_PROCESSING, "Processing"),
        (STATE_PROCESSED, "Processed"),
    )

    status = models.SmallIntegerField(choices=STATES,
        default=0, blank=True, null=True) 
    file = models.FileField(upload_to=settings.XML_ROOT)
    project = models.ForeignKey(Project)

    def __unicode__(self):
        return self.file.name

    def name(self):
        return os.path.basename(self.file.name)

    def save(self, *args, **kwargs):
        if not self.status:
            self.status = self.STATE_UPLOADED
        super(UploadedFile, self).save(*args, **kwargs)

    def delete(self, *args, **kwargs):
        os.remove(self.file.path)
        self.file.delete(False)
        super(UploadedFile, self).delete(*args, **kwargs)

class UploadedFileForm(forms.ModelForm):
    class Meta:
        model = UploadedFile
        excludes = ('project',)

Here is my view definition:

class UploadedFileCreateView(CreateView):
    model = UploadedFile

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.project_id = self.kwargs['proj_key']
        self.object.save()
        f = self.request.FILES.get('file')
        data = [{'name': f.name,
            'url': settings.MEDIA_URL + "files/" + f.name.replace(" ", "_"),
            'project': self.object.project.get().pk,
            'delete_url': reverse('fileupload:upload-delete',
                args=[self.object.id]),
            'delete_type': "DELETE"}]
        response = JSONResponse(data, {}, response_mimetype(self.request))
        response['Content-Disposition'] = 'inline; filename=files.json'
        return super(UploadedFileCreateView, self).form_valid(form)

    def get_context_data(self, **kwargs):
        context = super(UploadedFileCreateView, self).get_context_data(**kwargs)
        return context

Upvotes: 1

Views: 880

Answers (1)

Peter DeGlopper
Peter DeGlopper

Reputation: 37364

I see two likely problems:

1) The form keyword is exclude, not excludes.

Generally the recommendation is to favor explicitly listing fields to be included, so you don't accidentally expose any fields you might later add, but exclude will work.

2) You're not actually using your custom form class in the view. Set the form_class attribute to UploadedFileForm.

Upvotes: 1

Related Questions