Reputation: 633
Following is the FileModel to upload a csv file in my Django application:
class File(models.Model):
uploaded_by = models.ForeignKey(
User,
on_delete=models.CASCADE,
)
csv_file = models.FileField(
upload_to='csvfiles/',
)
On invocation of the /upload_file
url pattern, the upload_csv_file
view executes as follows:
def upload_csv_file(request):
if request.method == 'POST':
csv_form = CSVForm(request.POST, request.FILES)
if csv_form.is_valid():
file_uploaded = csv_form.save(commit=False)
file_uploaded.uploaded_by = request.user
csv_form.save()
return HttpResponse("<h1>Your csv file was uploaded</h1>")
elif request.method == 'GET':
csv_form = CSVForm()
return render(request, './mysite/upload_file.html', {'csv_form': csv_form})
In forms.py I am validating the following:
file size (5 mb)
class CSVForm(forms.ModelForm):
class Meta:
model = File
fields = ('csv_file',)
def clean_csv_file(self):
uploaded_csv_file = self.cleaned_data['csv_file']
if uploaded_csv_file:
filename = uploaded_csv_file.name
if filename.endswith(settings.FILE_UPLOAD_TYPE):
if uploaded_csv_file.size < int(settings.MAX_UPLOAD_SIZE):
# return True
return uploaded_csv_file
else:
raise forms.ValidationError(
"Error")
else:
raise forms.ValidationError("Error")
return uploaded_csv_file
# no need for a separate def clean()
# def clean(self):
# cleaned_data = super(CSVForm, self).clean()
# uploaded_csv_file = cleaned_data.get('csv_file')
# return uploaded_csv_file
However I encounter the following error on submitting the file upload button:
Attribute error: 'bool' object has no attribute 'get'
I am unsure whether the def clean_csv_file(self)
is being invoked or not.
There are ways to validate file extension and size within the function-based view, but I would like to validate the file attributes in the ModelForm's clean()
method itself.
UPDATE: Solution found
The def clean_csv_file(self) had to return an instance of uploaded_csv_file variable inplace of True.
Also, there is no need for clean() method if clean_field() is present in the ModelForm class.
Upvotes: 0
Views: 1501
Reputation: 599778
You should have shown the full error and traceback.
Nevertheless, the error caused by what you return from your clean_csv_file
. The return value of a clean function must always be the cleaned data itself; for a clean_field method, it must be the cleaned data for that field, and for the general clean method it must be the full cleaned_data dict. So:
def clean_csv_file(self):
uploaded_csv_file = self.cleaned_data['csv_file']
if uploaded_csv_file:
filename = uploaded_csv_file.name
if filename.endswith(settings.FILE_UPLOAD_TYPE):
if uploaded_csv_file.size < int(settings.MAX_UPLOAD_SIZE):
return uploaded_csv_file # Here
else:
raise forms.ValidationError(
"File size must not exceed 5 MB")
else:
raise forms.ValidationError("Please upload .csv extension files only")
return uploaded_csv_file
Note, your clean
method is also wrong, but the corrected version (which would return cleaned_data
) does nothing at all, so you should remove the whole thing.
Upvotes: 1