[Django]-Upload CSV file in django admin list view, replacing add object button

4👍

OP here, solution is as follows:

class SomeModelForm(forms.Form):
    csv_file = forms.FileField(required=False, label="please select a file")


class SomeModel(admin.ModelAdmin):
    change_list_template = 'admin/my_app/somemodel/change_list.html'

    def get_urls(self):
        urls = super().get_urls()
        my_urls = patterns("",
                           url(r"^upload_csv/$", self.upload_csv, name='upload_csv')
                       )
        return my_urls + urls

    urls = property(get_urls)

    def changelist_view(self, *args, **kwargs):
        view = super().changelist_view(*args, **kwargs)
        view.context_data['submit_csv_form'] = SomeModelForm
        return view

    def upload_csv(self, request):
        if request.method == 'POST':
            form = MineDifficultyResourceForm(request.POST, request.FILES)
            if form.is_valid():
                # process form

with the template overridden as so:

{% extends "admin/change_list.html" %}
{% load i18n admin_urls admin_static admin_list %}

{% block object-tools %}
    {% if has_add_permission %}
        <div>
            <ul class="object-tools">
                {% block object-tools-items %}
                    <form id="upload-csv-form" action="{% url 'admin:upload_csv' %}" method="post" enctype="multipart/form-data">
                    {% csrf_token %}
                        <p>{{ form.non_field_errors }}</p>
                        <p>{{ submit_csv_form.as_p }}</p>
                        <p>{{ submit_csv_form.csv_file.errors }}</p>
                        <p><input type="submit" value="Upload" />
                            <input type="reset" value="Reset"></p>
                    </form>
                {% endblock %}
            </ul>
        </div>
     {% endif %}
{% endblock %}

The form needs some custom validation but otherwise this solves the difficult part of customizing the admin page.

To elaborate what is going on here:

  1. get_urls is overridden so that an additional endpoint can be added to the admin page, this can point to any view, in this case it points upload_csv

  2. changelist_view is overridden to append the form info to the view

  3. the change_list.html template block “object-tools” is overridden with the form fields

Hopefully someone else finds this helpful as well.

👤xgadam

1👍

to your class SomeModelForm add something like this:

class Meta:
        model = YourModel
        fields = '__all__'

and change from forms.Form to forms.ModelForm

👤sebb

Leave a comment