I'm new with django and I was wondering if it is possible to change the status Currently(see the pic) of a filefield to other things like maybe: all, list... Because currently only return the last uploaded item. I have uploaded 5 file(File1, FIle2, .., File5) on a specific field, base on user ID, but it only return file5. I want to display all uploaded files and be able to get it via template.
I am able to see the complete list after the insertion in the db, via command prompt but only the last uploaded file is display in django admin.
My models.py :
class Student(models.Model):
name = models.CharField(max_length=400, null=True, blank=True)
codePerm = models.CharField(max_length=200, null=True)
files = models.FileField(blank=True, null=True)
admin.py :
@admin.register(Student)
class userdat(ImportExportModelAdmin):
list_display = ('name', 'codePerm', 'files')
pass
My project consists in processing data from an excel file. There are more than 10 000 elements in the excel file.
I can import the excel file into the sqlite DB and i can browse the data. However each student has files (5 files) associated with them that are saved locally in a folder that I need to add to the DB. I am looking for a way to import all 5 files per student in one go to save time instead of importing the files one by one for each student since I have over 10,000 students it would take me longer.
Is there a way to import the files grouped by student or what would be the best way to process the data? Thank you in advance for your help
CodePudding user response:
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.
CodePudding user response:
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 to create a custom form 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 form 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.