django rest 通过文件上传创建新的数据和对应的序列化方法

 

 

视图类

class FileCreateCinemaView(APIView):
    # authentication_classes = []
    permission_classes = [SupserPermisson|XD_Permisson,]

    def post(self, request):
        res = {'error':'','success':''}
        myfile = request._request.FILES.get('cinema_file',None)#获取上传的文件
        if not myfile:
            res['error'] = '请上传正确文件'
            return JsonResponse(data=res, code=400, desc="success", status=status.HTTP_400_BAD_REQUEST)
        name = request._request.META.get('REMOTE_ADDR',None)#获取客户端的地址
        li = func(myfile,name)#一个函数,用于处理上传的文件,将文件中的字段取出最终生成层一个list ,里边放的是字典
        data = CinemaInfoserializer(data=li,many=True)#可以将手工制作成的数据进行序列化,判断上传的数据正确性
        if data.is_valid():
            for i in data.validated_data:
                Cinema.objects.create(**i)
            return JsonResponse(data=res, code=200, desc="success", status=status.HTTP_200_OK)
        res['error']=data.errors
        return JsonResponse(data=res, code=400, desc="success", status=status.HTTP_400_BAD_REQUEST)

函数func  用户处理上传的excel中的数据,将期整理成dict并放到list中去

import xlrd
from common.tools.xd_errors import ParamError, ErrorCode
from common.tools.xd_msg_check import normalize_phone


def func(file,name):
import os path = os.getcwd() + '/temp/{0}.xls'.format(name) with open(path, 'wb') as f_write: # obj.chunks()就是指的是上传的具体数据 for chunk in file.chunks(): # 这里的chunk就是指的上传的文件的具体的数据 f_write.write(chunk) excel = xlrd.open_workbook(path) # 打开目标表格文件(填写路径) sheet = excel.sheets()[0] # 打开表格文件中的第一张表格,索引从0开始 nrows = sheet.nrows # 获取第一张表格的行数赋值给nrows li = [] for i in range(1, nrows): # 用一个for循环遍历所有的行数 j = sheet.row_values(i) if len(j)!=7: raise ParamError('请上传正确的文件', ErrorCode.EEEE) normalize_phone(j[4]) data = {"name": j[0], "theatres": j[1], "halls_num": j[2], "head": j[3], "phone": int(j[4]), "address": j[5], "dt": j[6]} #将每一行数据作为一个model中的一条整理好 li.append(data) #将整理好的数据放到li中 os.remove(path) # return li

序列化类

class CinemaInfoserializer(serializers.ModelSerializer):
    dt__name = serializers.SerializerMethodField()
    halls_num = serializers.SerializerMethodField()

    class Meta:
        model = Cinema
        fields = ['name','theatres','halls_num','head','phone','address','dt__name']

    def get_dt__name(self,obj):  #因为数据库中这个字段是外键关联的数据,而且用户上传的excel是上传这个县区的名称,所以重写方法
        return obj.dt.name

    def get_halls_num(self, obj):
        return Hall.objects.filter(cinema=obj.id).count()

 

数据库model

class Cinema(models.Model):
    name = models.CharField(max_length=64, null=False, default='',unique=True)
    theatres = models.CharField(max_length=64, null=False, default='')
    head = models.CharField(max_length=32, null=False, default='')
    phone = models.CharField(blank=True, max_length=11,)
    address = models.CharField(max_length=256, null=False, default='')
    dt = models.ForeignKey('District', on_delete=None,null=False,default=1)
class District(models.Model):
    district_id = models.CharField(max_length=8,null=False,unique=True)
    name = models.CharField(max_length=64,null=False,default='',unique=True)
    city = models.ForeignKey('City',to_field='city_id', on_delete=None,default=1)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = verbose_name = 'district'

 

posted on 2019-01-22 10:02  王大拿  阅读(559)  评论(0)    收藏  举报

导航