Django, want to upload eather image (ImageField) or file (FileField)
- by Serg
I have a form in my html page, that prompts user to upload File or Image to the server. I want to be able to upload ether file or image. Let's say if user choose file, image should be null, and vice verso. Right now I can only upload both of them, without error. But If I choose to upload only one of them (let's say I choose image) I will get an error:
"Key 'attachment' not found in <MultiValueDict: {u'image': [<InMemoryUploadedFile: police.jpg (image/jpeg)>]}>"
models.py:
#Description of the file
class FileDescription(models.Model):
TYPE_CHOICES = (
('homework', 'Homework'),
('class', 'Class Papers'),
('random', 'Random Papers')
)
subject = models.ForeignKey('Subjects', null=True, blank=True)
subject_name = models.CharField(max_length=100, unique=False)
category = models.CharField(max_length=100, unique=False, blank=True, null=True)
file_type = models.CharField(max_length=100, choices=TYPE_CHOICES, unique=False)
file_uploaded_by = models.CharField(max_length=100, unique=False)
file_name = models.CharField(max_length=100, unique=False)
file_description = models.TextField(unique=False, blank=True, null=True)
file_creation_time = models.DateTimeField(editable=False)
file_modified_time = models.DateTimeField()
attachment = models.FileField(upload_to='files', blank=True, null=True, max_length=255)
image = models.ImageField(upload_to='files', blank=True, null=True, max_length=255)
def __unicode__(self):
return u'%s' % (self.file_name)
def get_fields(self):
return [(field, field.value_to_string(self)) for field in FileDescription._meta.fields]
def filename(self):
return os.path.basename(self.image.name)
def category_update(self):
category = self.file_name
return category
def save(self, *args, **kwargs):
if self.category is None:
self.category = FileDescription.category_update(self)
for field in self._meta.fields:
if field.name == 'image' or field.name == 'attachment':
field.upload_to = 'files/%s/%s/' % (self.file_uploaded_by, self.file_type)
if not self.id:
self.file_creation_time = datetime.now()
self.file_modified_time = datetime.now()
super(FileDescription, self).save(*args, **kwargs)
forms.py
class ContentForm(forms.ModelForm):
file_name =forms.CharField(max_length=255, widget=forms.TextInput(attrs={'size':20}))
file_description = forms.CharField(widget=forms.Textarea(attrs={'rows':4, 'cols':25}))
class Meta:
model = FileDescription
exclude = ('subject',
'subject_name',
'file_uploaded_by',
'file_creation_time',
'file_modified_time',
'vote')
def clean_file_name(self):
name = self.cleaned_data['file_name']
# check the length of the file name
if len(name) < 2:
raise forms.ValidationError('File name is too short')
# check if file with same name is already exists
if FileDescription.objects.filter(file_name = name).exists():
raise forms.ValidationError('File with this name already exists')
else:
return name
views.py
if request.method == "POST":
if "upload-b" in request.POST:
form = ContentForm(request.POST, request.FILES, instance=subject_id)
if form.is_valid(): # need to add some clean functions
# handle_uploaded_file(request.FILES['attachment'],
# request.user.username,
# request.POST['file_type'])
form.save()
up_f = FileDescription.objects.get_or_create(
subject=subject_id,
subject_name=subject_name,
category = request.POST['category'],
file_type=request.POST['file_type'],
file_uploaded_by = username,
file_name=form.cleaned_data['file_name'],
file_description=request.POST['file_description'],
image = request.FILES['image'],
attachment = request.FILES['attachment'],
)
return HttpResponseRedirect(".")