0π
With models.FileField
in your Student
model you can add only one file for each student. Every new upload replaces the old file. That is why in the admin you only see the file that is currently in the database. If you want to add more than one file for each student, you need to use ForeignKey and Inline. Here is an example (you need to adjust it to work with your ImportExportModelAdmin
class):
models.py
class Student(models.Model):
name = models.CharField(max_length=400, null=True, blank=True)
codePerm = models.CharField(max_length=200, null=True)
class StudentFiles(models.Model):
student = models.ForeignKey('Student',
on_delete=models.CASCADE,
related_name='files'
)
file = models.FileField()
admin.py
from .models import Student, StudentFiles
class StudentFilesInline(admin.TabularInline):
model = StudentFiles
@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
inlines = [StudentFilesInline,]
Now if you want to upload multiple files at once, you are going to need a custom form field for this. I find this tutorial helpful. For example, you can create forms.py
in your app and add this code:
forms.py
from django import forms
from .models import Student, StudentFiles
class StudentAdminForm(forms.ModelForm):
class Meta:
model = Student
# Display all default fields without change
fields = '__all__'
# Create a new field with 'multiple' attribute
files = forms.FileField(
widget=forms.ClearableFileInput(attrs={'multiple': True}),
label='Upload multiple files at once',
required=False,
)
def save_files(self, student):
# Save each file in the StudentFiles model
for upload in self.files.getlist('files'):
file = StudentFiles(student=student, file=upload)
file.save()
And then adjust the admin.py
accordingly:
from django.contrib import admin
from .models import Student, StudentFiles
from .forms import StudentAdminForm
class StudentFilesInline(admin.TabularInline):
model = StudentFiles
@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
inlines = [StudentFilesInline,]
form = StudentAdminForm
def save_related(self, request, form, formsets, change):
super().save_related(request, form, formsets, change)
form.save_files(form.instance)
With all of this you will be able to upload many files at once and later replace/delete any of them.
EDIT: There is a simpler way explained in this Quora post. You can get rid of the save_files()
and save_related()
. Use save_model()
instead:
forms.py
from django import forms
from .models import Student
class StudentAdminForm(forms.ModelForm):
class Meta:
model = Student
# Display all default fields without change
fields = '__all__'
# Create a new field with 'multiple' attribute
files = forms.FileField(
widget=forms.ClearableFileInput(attrs={'multiple': True}),
label='Upload multiple files at once',
required=False,
)
admin.py
from django.contrib import admin
from .models import Student, StudentFiles
from .forms import StudentAdminForm
class StudentFilesInline(admin.TabularInline):
model = StudentFiles
@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
inlines = [StudentFilesInline,]
form = StudentAdminForm
def save_model(self, request, obj, form, change):
obj.save()
for file in request.FILES.getlist('files'):
obj.files.create(file=file)
1π
You would need to override the ClearableFileInput using formfield_overrides.
Something like the following
from django.contrib import admin
from django.forms import ClearableFileInput
class MyModel(admin.MyModel):
formfield_overrides = {
models.FileField {'widget':ClearableFileInput(template_name='template.html')},
}
You will have to create a new template change that there, here is how it is implemented in django source.