野外泛在线考核系统(七)

二、笔记本端

接(六),主要实现数据管理

(五)数据管理

在这3天都在折腾利用form.py实现数据管理,特别是文件上传,多个文件上传的事情,之前文件上传其实已经没有问题,但问题是不是用form.py实现的,这里主要是想通过form.py实现,因此又折腾了这么久。主要参考《Django3 Web应用开发实践》(黄永祥著)这本书8.9多文件上传的例子。遇到了很多的问题,今天好好梳理下

1.数据重新迁移

在最开始设计数据表的时候,可能不是很完善,到后来又想增加几个字段,或者各表再建立相关联系等等,对于初学者很常见,因此,就会涉及到重新进行迁移,但这里需要注意几个问题
注意
1.迁移后在mysql中所有表名都是小写的,意味着如果在models.py中字母相同,但大小写不同的两个表,在mysql中是一个表,会冲突
2.models.py的各个表中如果有相同名称的字段,迁移时也可能会发生冲突,比如student表中有个ID字段(不是默认的,是自定义的),teancher表中也有个ID字段(不是默认的,是自定义的)那么迁移时就会报错,为了不冲突,建议分别改成studentID和teacherID。
如果迁移途中发生错误,希望从头再来,可按照如下步骤实施:

  1. 打开终端(我是麒麟系统)
    在这里插入图片描述
    在这里插入图片描述
  2. 登录mysql
tactics@qbpb:~$ mysql -u root -p
  1. 直接删除数据库
mysql> drop database artillery
  1. 重新创建数据库
mysql> CREATE DATABASE qbpb
  1. 打开pycharm,删除Lesson/migrations下除__int__.py以外的所有文件。
    在这里插入图片描述
  2. 重新设置setting.py数据库设置,因为数据库改名了(不改名可略过),而后执行数据迁移:
python manage.py makemigrations
python manage.py migrate

采取这样的方法,也省去了折腾,但如果有数据那就不好办了,可能得另寻别的方法。

2.通过form.py实现信息录入和多文件上传

  1. 在Lesson/form.py中,加入如下内容,这里主要参考了Django官方文件上传
class MultipleFileInput(forms.ClearableFileInput):
   allow_multiple_selected = True

class MultipleFileField(forms.FileField):
   def __init__(self, *args, **kwargs):
       kwargs.setdefault("widget", MultipleFileInput())
       super().__init__(*args, **kwargs)
   def clean(self, data, initial=None):
       single_file_clean = super().clean
       if isinstance(data, (list, tuple)):
           result = [single_file_clean(d, initial) for d in data]
       else:
           result = single_file_clean(data, initial)
       return result
       
class StudentForm(forms.ModelForm):
   # allow_empty_file=True 是允许上传空文件
   #studentPhoto = forms.FileField(label='照片', allow_empty_file=True,widget=forms.ClearableFileInput(attrs={'multiple': False}))
   studentPhoto = MultipleFileField(label='照片', allow_empty_file=True)
   class Meta:
       model = Student
       fields = '__all__'
       labels = {
           'studentID': '编号',
           'studentName': '姓名',
           'studentGender': '性别',
           'studentIDPhoto': '照片'
       }
       error_messages = {
           '__all__': {'required': '请输入内容',
                       'invalid': '请检查输入内容'},
       }

  1. 《Django3 Web应用开发实践》(黄永祥著)这本书8.9多文件上传的例子中是这样的,但会报错ValueError: ClearableFileInput doesn’t support uploading multiple files
studentPhoto = forms.FileField(label='照片', allow_empty_file=True,widget=forms.ClearableFileInput(attrs={'multiple': False}))
  1. 为了解决错误,需要改成这样才行。
studentPhoto = MultipleFileField(label='照片', allow_empty_file=True)
  1. 在Lesson下新建adminViews.py
# adminViews.py
from django.shortcuts import render
from django.http import HttpResponse
from .form import *
from .models import *
from django.conf import settings
import os

def adminData(request):
    # GET请求
    if request.method == 'GET':
        id = request.GET.get('id', '')
        if id:
            i = Student.objects.filter(id=id).first()
            p = StudentForm(instance=i)
        else:
            p = StudentForm()
        return render(request, 'manage.html', locals())
    # POST请求
    else:
        p = StudentForm(data=request.POST, files=request.FILES)
        if p.is_valid():
            name = p.cleaned_data['studentName']
            result = Student.objects.filter(studentName=name)
            # 数据不存在,则新增数据
            if not result:
                p = p.save()
                id = p.id
                # 遍历上存的文件,依次添加证件信息
                # 如果网页有多个文件上存控件
                # 可以通过getlist方法获取指定的文件上存控件
                for f in request.FILES.getlist('studentPhoto'):
                    # 修改文件名
                    # 如果不同用户上存相同文件名的文件
                    # 防止media文件夹会覆盖文件
                    f.name = f'{id}.'.join(f.name.split('.'))
                    d = dict(student_id=id, studentPhoto=f)
                    StudentPhoto.objects.create(**d)
                return HttpResponse('新增成功')
            # 数据存在,则修改数据
            else:
                studentID = p.cleaned_data['studentID']
                d = dict(studentName=name, studentID=studentID)
                result.update(**d)
                # 删除旧的证件
                id = result.first().id
                # 删除media文件夹的文件,然后删除数据表的数据
                for c in StudentPhoto.objects.filter(student_id=id):
                    # c.studentPhoto是文件对象,通过name属性获取文件名
                    # 删除media文件夹的文件
                    fn = c.studentPhoto.name
                    os.remove(os.path.join(settings.MEDIA_ROOT, fn))
                    # 删除数据表的数据
                    c.delete()
                # 添加新的证件
                for f in request.FILES.getlist('studentPhoto'):
                    # 修改文件名
                    # 如果不同用户上存相同文件名的文件
                    # 防止media文件夹会覆盖文件
                    f.name = f'{id}.'.join(f.name.split('.'))
                    d = dict(student_id=id, studentPhoto=f)
                    StudentPhoto.objects.create(**d)
                return HttpResponse('修改成功')
        else:
            # 获取错误信息,并以json格式输出
            error_msg = p.errors.as_json()
            print(error_msg)
            return render(request, 'manage.html', locals())
  1. 而后修改Lesson/urls.py,
# urls.py
from django.urls import path
from . import views
from .views import *
from .adminViews import *

urlpatterns = [
    path('', views.index,name='index'),
 	# 管理数据
    path('adminData', adminData, name='adminData'),
]
  1. 然后新建一个manage.html
    在这里插入图片描述
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {% if v.errors %}
        <p>
            数据出错啦,错误信息:{{ v.errors }}
        </p>
    {% else %}
        <form action="" method="post" enctype="multipart/form-data">
        {% csrf_token %}
            <ul>
                <li>编号:{{ p.studentID }}</li>
                <li>姓名:{{ p.studentName }}</li>
                <li>性别:{{ p.studentGender }}</li>
                <li>证件:{{ p.studentIDPhoto }}</li>
                <li>照片:{{ p.studentPhoto }}</li>
            </ul>
            <input type="submit" value="提交">
        </form>
    {% endif %}
</body>
</html>

在index.html中加入链接:

<a href="adminData"><h3 >管理数据</h3></a>

至此,文件下载,上传功能完工,最终效果。
在这里插入图片描述

  • 19
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值