DEV Community

Cover image for Django Import and Export (Including PDF)
Chukwuemeka Nwaoma
Chukwuemeka Nwaoma

Posted on

Django Import and Export (Including PDF)

As the name suggests, this project covers a basic import and export in Django using the django-import-export package.

I have tried to implement a common feature of importing and exporting data to and from the model via the admin panel while also digging deeper into bringing the export feature to the views and passing it straight to the template.

While the django-import-export package does not cover exporting to PDF, I have implemented that a PDF export together with a few others like CSV, XLS and JSON and made them downloadable in one selection and click.

Let's get started with the codes!

First, set up a Django project with a basic model. In my case, I have made it a bit tougher by creating two related models.

Visit https://django-import-export.readthedocs.io/en/latest/api_widgets.html
to install django-import-export, then set up the admin import-export mixins.

Introduce a dehydrate[field]_ function for fields with foreign keys and instantiate them in the resources class.

class BookResource(resources.ModelResource):
    author = Field()
    created = Field()

    class Meta:
        model = Book
        fields = ('id', 'title', 'author', 'publish_status', 'created')
        export_order = ('id', 'title', 'author', 'publish_status', 'created')

    def dehydrate_author(self, obj):
        return obj.author.name

    def dehydrate_created(self, obj):
        return obj.created.strftime("%d-%m-%y")


class BookAdmin(ImportExportActionModelAdmin):
    resource_class = BookResource

admin.site.register(Author)
admin.site.register(Book, BookAdmin)
Enter fullscreen mode Exit fullscreen mode

When that is done, you'll notice the import and export buttons on the admin dashboard, and that is all.

Image description

However, to bring this feature from the views to the template, start off with creating a resources.py file, importing the models, as well as the resources and fields from import_export.

Write a resources class just like with the admin.py file and write its meta class too.

Move to the views and use a created form to collect predefined responses, then match each response to a format and return.

# If User Selects CSV Format
            if dataFormat == 'csv':
                book_resource = BookResource()
                dataset = book_resource.export()
                response = HttpResponse(dataset.csv, content_type='text/csv')
                response['Content-Disposition'] = 'attachment; filename="books.csv"'
                return response
Enter fullscreen mode Exit fullscreen mode

For the PDF format, import weasyprint and also install GTK3-Runtime if on a windows machine, and don't forget to add to path.

 # If User Selects PDF Format   
            elif dataFormat == 'pdf':
                # obj = Book.objects.all()
                template = get_template('core/pdf-output.html')
                html = template.render(context)
                response = HttpResponse(content_type='application/pdf')
                result = HTML(string=html).write_pdf(response)
                response['Content-Disposition'] = 'attachment; filename="books.pdf"'
                response['Content-Transfer-Encoding'] = 'binary'
                return response

Enter fullscreen mode Exit fullscreen mode

Create an output template, pass the template name to the views, then write pdf, and that's all. Too Easy.

<div class="jumbotron">
            <table class="table table-bordered">
                <thead>
                    <tr>
                        <th>Title</th>
                        <th style="text-align: center;" colspan="2">Author</th>
                        <th>Status</th>
                        <th>Date Created</th>
                    </tr>    
                    <tr>
                        <th></th>
                        <th><em class="text-muted">Name</em></th>
                        <th><em class="text-muted">Gender</em></th>
                        <th></th>
                        <th></th>
                    </tr>            
                </thead>
                <tbody>
                    {% for book in obj %}
                        <tr>   
                            <td>{{book.title}}</td> 
                            <td>{{book.author}}</td> 
                            <td>{{book.author.gender}}</td> 
                            <td>{{book.publish_status}}</td> 
                            <td>{{book.created|date:"M. d, Y"}}</td> 
                        </tr>
                    {% endfor %}

                </tbody>
            </table>

            <br>

            <div style="display: flex; height: 40px;">
                <form method="post" style="margin-top: 1px; margin-right: 10px; font-size: medium;">
                    {% csrf_token %}
                    {{form}}
                    <input type="submit" style="height: 33px;" class='btn btn-primary' value="Go">
                </form>
            </div>


        </div>

Enter fullscreen mode Exit fullscreen mode

Image description

Image description

Image description

Check out https://doc.courtbouillon.org/weasyprint/latest/first_steps.html for more details on weasyprint.

Check out the complete code repo on https://github.com/joelchooks/import_export

Top comments (2)

Collapse
 
pkombala profile image
pkombala

how to import my json data to django model please help me I am facing error because of foreignKey

Collapse
 
joelchuks profile image
Chukwuemeka Nwaoma

Hi, please reach out to me via email. My email is visible on my dashboard. Regards.