Reputation: 2449
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
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