In the previous section, we saw how we can create a custom action to export the data displayed in the admin page. We exported the data as a csv file. Now, defining a custom function to export data for every model will be time consuming and a repetitive task, and also according to different formats the logic for exporting the data would change.
Instead, we can use a library that is available in django to handle the export of data in different formats.
django-import-export
is a Django library that provides a set of tools for importing and exporting data from and to various formats in Django applications. It simplifies the process of working with tabular data and integrates seamlessly with the Django admin interface. With django-import-export
, you can easily import data from sources like CSV, Excel, JSON, and export data to these formats.
To export using the library, first we would need to install it, which can be done using the following command :
pip install django-import-export
Next it needs to be added inside the INSTALLED_APPS
in settings.py file :
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'tailwind',
'theme',
'authentication',
'event',
'import_export',
]
After this has been done, we can create import-export resources and assign it to our model in admin.py
file.
So, we will create a new file named resources.py
in the event
app.
from import_export import resources
from .models import Workshopregistration
class WorkshopRegistrationResource(resources.ModelResource):
class Meta:
model = Workshopregistration
fields = ['workshop__workshop_title', 'workshop__venue', 'student__first_name', 'student__email', 'student__mobile_number']
So here we have created a resource class, with the fields we want to be exported. Now, this resource needs to be assigned in the corresponding admin class.
Inside the event/admin.py
file :
from .resources import WorkshopRegistrationResource
from import_export.admin import ExportActionModelAdmin
@admin.register(Workshopregistration)
class WorkshopRegistrationAdmin(ExportActionModelAdmin,admin.ModelAdmin):
list_display = ('workshop', 'student', 'registered_date')
search_fields = ('workshop__name', 'student__email')
list_filter = ('registered_date', 'workshop')
autocomplete_fields = ('workshop', 'student')
resource_class = WorkshopRegistrationResource
def get_queryset(self, request):
qs = super().get_queryset(request)
if not request.user.is_superuser:
qs=qs.filter(workshop__department = request.user.hodprofile.department)
return qs
Now, we have removed our custom action. Now when we visit the admin page, we would be able to see it like this.
So the django-import-export
allows, the data to be downloaded in these file types.
When the data is downloaded as a xlsx file it would come like this :
workshop__workshop_title | workshop__venue | student__first_name | student__email | student__mobile_number |
---|---|---|---|---|
Cyber Secuirty Fundamentals | Sapphire Auditorium | Mustafa | mustafa@edkool.com | 1234567890 |
Block Chain Technology | Main Seminar Hall | Mustafa | mustafa@edkool.com | 1234567890 |
When the data is downloaded as a json file, it would come like this :
[{"workshop__workshop_title": "Cyber Secuirty Fundamentals", "workshop__venue": "Sapphire Auditorium", "student__first_name": "Mustafa", "student__email": "mustafa@edkool.com", "student__mobile_number": "1234567890"}, {"workshop__workshop_title": "Block Chain Technology", "workshop__venue": "Main Seminar Hall", "student__first_name": "Mustafa", "student__email": "mustafa@edkool.com", "student__mobile_number": "1234567890"}]
When the data is downloaded as yaml it would come as follows :
- {student__email: mustafa@edkool.com, student__first_name: Mustafa, student__mobile_number: '1234567890', workshop__venue: Sapphire Auditorium, workshop__workshop_title: Cyber Secuirty Fundamentals}- {student__email: mustafa@edkool.com, student__first_name: Mustafa, student__mobile_number: '1234567890', workshop__venue: Main Seminar Hall, workshop__workshop_title: Block Chain Technology}
So now it allows the data to be downloaded in multiple formats very easily.
For further customization and import functions you can visit its documentation : https://django-import-export.readthedocs.io/en/stable/
Talking about some further customizations, it is possible to decide the import and export formats accordingly.
For specifying the import and export types, in the settings.py
file add the following code :
from import_export.formats.base_formats import CSV, XLSX
EXPORT_FORMATS = [XLSX]
IMPORT_FORMATS = [CSV, XLSX]
This will restrict the formats to the one specified. Also, one more question arises here which is, is the resource class necessary? The answer to this question can be based on the fields we want, if we want some relation fields then we would need to define the custom resource class, without that even data can be exported.
@admin.register(Workshopregistration)
class WorkshopRegistrationAdmin(ExportActionModelAdmin,admin.ModelAdmin):
list_display = ('workshop', 'student', 'registered_date')
search_fields = ('workshop__name', 'student__email')
list_filter = ('registered_date', 'workshop')
autocomplete_fields = ('workshop', 'student')
# resource_class = WorkshopRegistrationResource
def get_queryset(self, request):
qs = super().get_queryset(request)
if not request.user.is_superuser:
qs=qs.filter(workshop__department = request.user.hodprofile.department)
return qs
Here, the resource_class
has been commented and export limit from the settings.py
has also been removed.
Now, if we try to download the data, it would come like this :
[{"id": 2, "workshop": 3, "student": 4, "registered_date": "2023-12-12 06:45:30"}, {"id": 1, "workshop": 2, "student": 4, "registered_date": "2023-12-06 03:06:26"}]
It would return the data as of that stored in the database.
If you try to download as xlsx
, it would come as follows :
id | workshop | student | registered_date |
---|---|---|---|
2 | 3 | 4 | 2023-12-12 06:45:30 |
1 | 2 | 4 | 2023-12-06 03:06:26 |
Downloading as html
would give it as follows :
<table>
<thead>
<tr><th>id</th>
<th>workshop</th>
<th>student</th>
<th>registered_date</th></tr>
</thead>
<tbody>
<tr><td>2</td>
<td>3</td>
<td>4</td>
<td>2023-12-12 06:45:30</td></tr>
<tr><td>1</td>
<td>2</td>
<td>4</td>
<td>2023-12-06 03:06:26</td></tr>
</tbody>
</table>
If you want all the fields without any customization, then it would be possible even without a resource class.