django页面导入导出,文件上传

django页面导入导出

导出的业务比较通用,广泛,需要开发效率,可以使用 django_import_export

导入,业务不常用,但需要定制化,错误消息要详细,用django_import_export导入,一般用在后台或开发人员自己转移数据。 但提供给前台用户,

还需要选择可定制的,我选择django_tablib插件。

 

一、导出

可定制:改变列名,增加model不存在的列名,foreign关联提取等等

(1)定义resource,关联model

from import_export import resources
from d3.models import *
from userapp.models import *
from import_export.fields import Field

class StudentResource(resources.ModelResource):
    #导出来的Excel,列名全是字段名,也就是英文的,但我想中文列名
    id = Field(attribute='id', column_name='编号')
    name = Field(attribute='name', column_name='姓名')
    sfz = Field(attribute='sfz', column_name='身份证')
    name = Field(attribute='name', column_name=Student.name.field.verbose_name)
    new_field = Field(column_name='一个新的字段')
    class Meta:
        model = Student
    #导出的数据中加入Model里不存在的字段,dehydrate是固定关键字
    @staticmethod
    def dehydrate_new_field(instance: Student):
        return '新字段内容'

class UserResource(resources.ModelResource):

    class Meta:
        model = User
        '''
        fields = ('id', 'name', 'author', 'price',)  : 指定导出的字段
        export_order = ('appid','name')  : 指定导出的顺序
        exclude = ('id',)  : 不用导出的内容
        import_id_fields = ('sfz',)  
        #数据库已有人,现需要导入一个Excel来更新人,需把一字段设成主key,不然导入就变成新增了,
        一般Excel里不会有数据库主键id的,所以这里用身份证sfz(假设sfz不重复,按sfz更新)
        
        '''

        '''
        导出
        Jg_dataset = JgResource().export()
        Jg_dataset.csv #导出csv数据
        Jg_dataset.json #导出json数据
        
        过滤导出
        queryset = Jg.objects.filter(location='Helsinki')
        Jg_dataset = JgResource().export(queryset)
        '''

(2) 编写view

def export_demo(request):

    if request.method == 'POST':
        file_format = request.POST['file-format']
        employee_resource = StudentResource()
        queryset = Student.objects.filter(xiangzhen='景山街道')
        dataset = employee_resource.export(queryset)
        if file_format == 'CSV':
            response = HttpResponse(dataset.csv, content_type='text/csv')
            response['Content-Disposition'] = 'attachment; filename="exported_data.csv"'
            return response
        elif file_format == 'JSON':
            response = HttpResponse(dataset.json, content_type='application/json')
            response['Content-Disposition'] = 'attachment; filename="exported_data.json"'
            return response
        elif file_format == 'XLS (Excel)':
            response = HttpResponse(dataset.xls, content_type='application/vnd.ms-excel')
            response['Content-Disposition'] = 'attachment; filename="exported_data.xls"'
            return response

    return render(request, 'd3/export_demo.html')

html

{% block content %}
    <h3>Export Data</h3>
    <p>exporting from database</p>
    <form method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <p>Please select format of file.</p>
        <select name="file-format" class="form-control my-3">
            <option selected>Choose format...</option>
            <option>CSV</option>
            <option>JSON</option>
            <option>XLS (Excel)</option>
        </select>
        <button class="btn btn-primary" type="submit">Export</button>
    </form>
    <a href="{% url 'd3:home' %}">Return Home View</a>
{% endblock %}

 

二、导入

官网 django_import_export也有很多可定制方案,但错误消息很难以定制,例子如下:(但我不推荐)

from d3.resources import StudentResource
from tablib import Dataset

def
import_demo(request): baseerrors=[] rowerrors=[] invaliderrors=[] context = {} if request.method == 'POST': file_format = request.POST['file-format'] employee_resource = StudentResource() dataset = Dataset() new_employees = request.FILES['importData'] if file_format == 'CSV': imported_data = dataset.load(new_employees.read().decode('utf-8'),format='csv') result = employee_resource.import_data(dataset, dry_run=True) elif file_format == 'JSON': imported_data = dataset.load(new_employees.read().decode('utf-8'),format='json') result = employee_resource.import_data(dataset, dry_run=True) elif file_format == 'xls': imported_data = dataset.load(new_employees.read(),format='xls') result = employee_resource.import_data(dataset, dry_run=True) if not result.has_errors(): employee_resource.import_data(dataset, dry_run=False) print(imported_data.__dict__) for data in imported_data : print(data[0],data[1],data[2]) baseerrors=result.base_errors rowerrors=result.row_errors() invaliderrors=result.invalid_rows context['baseerrors'] = baseerrors context['rowerrors'] = rowerrors context['invaliderrors'] = invaliderrors return render(request, 'd3/import_demo.html',context)

 

推荐的导入方案,利用tablib


from d3.resources import StudentResource
from tablib import Dataset
def import_can_custom(request): context = {} if request.method == 'POST': file_format = request.POST['file-format'] employee_resource = StudentResource() dataset = Dataset() new_employees = request.FILES['importData'] imported_data = dataset.load(new_employees.read(),format='xls') obj_list=[] for data in imported_data : print(data[0],data[1],data[2]) obj=Student( name=data[1], sfz=data[2], ) obj_list.append(obj) Student.objects.bulk_create(obj_list) return render(request, 'd3/import_demo.html',context)
 

 

导入html

 

{% block content %}
    <h3>Import Data</h3>
    <p>importing to database</p>
    <form method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <input type="file" name="importData">
        <p>Please select format of file.</p>
        <select name="file-format" class="form-control my-3">
            <option selected>Choose format...</option>
            <option>CSV</option>
            <option>JSON</option>
            <option>xls</option>
        </select>
        <button class="btn btn-primary" type="submit">Import</button>
    </form>
    <a href="{% url 'd3:home' %}">Return Home View</a>
    <div>
        {{baseerrors  }}
        {{rowerrors  }}
        {{invaliderrors  }}

    </div>

 

另一个导入的例子

def uploadFile(request):
    if request.method == 'POST':
        dataset = Dataset()
        newStudent = request.FILES['myfile']
        if not newStudent.name.endswith('xlsx'):
            messages.info(request, 'Wrong format')
            return render(request, 'file.html')

        loadedData = dataset.load(newStudent.read(), format='xlsx')
        for data in loadedData:
            value = Student(
                data[0],
                data[1],
                data[2],
                data[3],
            )
            value.save()
    return render(request, 'file.html')

 

posted @ 2023-06-29 10:16  花生与酒  阅读(530)  评论(0编辑  收藏  举报