• python-web开发[20]之开发小结



    1.知识点复习

    1.1 基础入门

    • 编码
    编码基础知识点:utf-8、unicode、gbk、ascii
    默认解释器编码:
    	- Python2:ascii( # -*- coding:utf-8 -*- )
    	- Python3:utf-8(重要)
    
    • 1
    • 2
    • 3
    • 4
    • 输入和输出
    print
    input,用户输入的永远是字符串类型。
    
    data = input("请输入序号:") # 1
    print(data) # "1"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 变量
    规范:字母、数字、下划线;数字不能开头;不能是py内置关键字。
    建议:
    	- 见名知意
        - 多个单词,用下划线连接。
        - 全局变量用大写( DATA_LIST、USER_INFO  );局部变量小写(user_age)。
        
    注意:
    	全局变量    GET_INFO
        局部变量    get_info
    	函数名      get_info
        类名        GetInfo
        文件名      get_info
        包名称      get_info
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 异常处理【补充】
    data = input("请输入:")  # 你好
    res = int(data)
    print(res)
    
    # 这个代码是有风险,可能会报错。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 循环中for/while内部都可以用 break、continue
    • 字符串格式化
    data = "我是{},姓名是{},年龄是{}".format("xx",123,999)
    
    data = "我是{0},姓名是{1},年龄是{2}".format("xx",123,999)
    
    data = "我是{0},姓名是{0},年龄是{2}".format("xx",123)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 运算符
    - 传统的运算符
    - 逻辑运算符
    	- 常见操作,最终的到的结果:True/False
    		if 1>10 and 9<8:
    			pass
    		else:
    			pass
    	- 非传统,最终的结果是:第一个或第二个值。
    		data = 值1 and 值2
    		v1 = 5 and 9  # 9
    		v2 = 0 and 10 # 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    1.2 数据类型

    • 字符串类型
    - 不可变类型;
    - 常见方法:strip/split/replace/join
    	v1 = "root"
    	data = v1.upper()
    	print(v1)   # root
    	print(data) # ROOT
    	
    - 公共:索引、切片、循环
    	v1 = "root"
    	v1[1] = "X"  # 报错,不可变
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 列表类型
    - 可变类型
    - 常见方法:append/insert/pop/remove
    - 公共:索引、切片、循环
    	v1 = [11,22,33,44,55]
    	
    	v1[0]
    	v1[1:3]      - 前取后不取
    	v1[1:-1]
    - 列表的推导式
    	data = [ i for i in range(10)]
    	data = [ i for i in range(10) if i<5]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 字典类型
    - 可变类型
    - 字典的键是有要求:可哈希类型,目前不可哈希:list/dict/set。
    - 扩展:python3.6+字典有序。
    - 常见的功能:keys、values、items、get
    	data = {}
    	v1 = data.get("k1")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 关于元组
    v1 = (11,)
    v2 = (11)   # 11
    v3 = 11
    
    • 1
    • 2
    • 3
    • 其他数据类型
    其他类型转布尔类型时,哪些为False: 空、0、None
    其他类型转自己类型时,自己的类名()
    	int("123")
    
    • 1
    • 2
    • 3

    1.3 函数

    • 定义
    def func():
        pass
    
    func()
    
    • 1
    • 2
    • 3
    • 4
    • 参数
    def func(v1,v2):
        pass
    
    def func(v1, v2=None):
        pass
    
    def func(*args,**kwargs):
        pass
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 返回值
    - 没有返回值,默认返回None
        def func(v1,v2):
            print(999)
    - 一个返回值
        def func(v1,v2):
            return 123
        
        res = func(1,2)
        print(res) # 123
        
    - 多个返回值
        def func(v1,v2):
            return 123,999,123
        
        res = func(1,2)
        print(res) # (123,999,123)
        
        
    	def func(v1,v2):
            return 123,999,123
        
        d1,d2,c3 = func(1,2)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • lambda表达式(匿名函数)
    def func(arg):
        return arg + 100
    
    func = lambda arg:arg+100
    v1 = func(100)
    print(v1) # 200
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 内置函数
    max/min/all/any/help/hex/oct/bin..
    
    open,文件操作。
        f = open("xx.log",mode='r')
        data = f.read()
        f.close()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 文件操作
    - 模式:r/w/a ; rb/wb/ab
    - 打开 & 关闭
    	with open("xx.log",mode='r') as f:
    		f.read()
    
    • 1
    • 2
    • 3
    • 4

    1.4 模块

    • 分类
    - 自定义模块:自己写文件/文件夹
    - 内置模块:time/datetime/json/hashlib/random/re等
    - 第三方模块:openpyxl/requests/bs4/flask/django等
    
    • 1
    • 2
    • 3
    • 自定义模块
    - sys.path,Python内部导入模块时,根据目录去寻找。
    - 一定不要让自己写的模块名和内置的模块名重复(***)
    - 导入模块:
    	import xxx
    	from xxx import xxx
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 内置模块
    - 时间部分:time/datetime/字符串类型。
    - random:随机生成数字。
    - hashlib:加密(md5加密、md5加密+加盐) 防止被撞库。
    - json:
    	- JSON格式的字符串: 内部字符串双引号、内部[] 
    	- json.dumps
    	- json.loads
    - re和正则
    	- 正则:\d \w ; 贪婪匹配。
    	- re.search/re.match/      re.findall
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 第三方模块
    - 安装第三方模块:pip、源码、wheel
    - 常见第三方模块:
    	- requests
    	- bs4
    	- openpyxl
    	- python-docx
    	- flask/django (flask简洁(轻量级);django功能强大)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    1.5 面向对象

    - 面向对象的三大特性:封装、继承、多态。
    - 理解,读懂源码和代码。
    
    • 1
    • 2

    1.6 MySQL数据库

    - 数据库
    - 表
    - 数据行
    更多知识:https://www.bilibili.com/video/BV15R4y1b7y9
    
    • 1
    • 2
    • 3
    • 4
    show databases;
    use 数据库;
    
    show tables;
    desc 表名;
    
    select * from 表;
    insert into 表(列,列,列)values(...)
    update  表 set 列=值;
    delete from 表 where 条件;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Python连接并操作MySQL:

    • pymysql 【自己原生写】
    pip install pymysql
    
    • 1
    • mysqlclient 【django内部】
    pip install mysqlclient
    
    • 1
    • MySQLdb (默认不支持python3)
    pip intall MySQLdb
    
    • 1

    当使用Python代码去操作MySQL时,一定要防止SQL注入的问题。

    # SQL语句不要用字符串格式化去拼接。
    
    import pymysql
    # 1.连接MySQL
    conn = pymysql.connect(host="127.0.0.1", port=3306, user='xxx', passwd="xxx", charset='utf8', db='unicom')
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    
    # 【错误】不要这么写
    sql = "select * from admin where id > %s".format(2)
    cursor.execute(sql)
    # 【正确】这么写
    cursor.execute("select * from admin where id > %s", [2, ])
    
    # 获取符合条件的第一条数据,字典    None
    res = cursor.fetchone()
    print(res)  # {'id': 3, 'username': 'xxx', 'password': 'xxx', 'mobile': '1999999999'}
    
    # 3.关闭连接
    cursor.close()
    conn.close()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    1.7 前端开发

    • HTML
    - 块级和行内标签(div、span)
    	块级:div/h系列
    	行内:span/a (设置高度、宽度、边距无效)
    - Form表单
    	
    - 关于a标签 百度 超链接去跳转。 做锚点 第一章 第二章
    第一章 谢新雪
    第二章 单独的
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • CSS
    - 位置
    	- 标签 
    - style代码块 - 文件中 - 选择器 div { } #v1 { } .v2 { } div[xx='11'] { } - 样式 color;fonts-ize; background-color; padding; margin; float:left; ,脱离文档流。 clear:both; :after
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • JavaScript & jQuery
    - 本质上:找到标签;操作标签。
    
    - 找标签
    	$("#x1")
    	$(".x1")
    	$("div")
    	
    	$("input[type='text']")   找到 input 标签且 type='text'
    - 操作标签
    	$("#x1").text()            
    dd
    $("#x1").text("xxx")
    xxx
    $("#x1").val() $("#x1").val("xxx") $("#x1").attr("uu")
    dd
    $("#x1").attr("uu","999")
    dd
    $("#x1").empty()
    dd
    - 清空内容 $("#x1").remove()
    dd
    - 整个标签删除
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • BootStrap
    - 支持响应式布局,根据屏幕的宽度调整布局。
    - 栅格,12份。
    - 常见的样式:
    	- container  / container-fluid
    	- 面板
    	- 按钮
    	- 表单
    	- 表格
    	- 对话框
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 第三方插件
    - 插件一般都包含:CSS、JavaScript,开发使用时候
    	- 引入css、js(依赖jQuery)
    	- 使用
    
    • 1
    • 2
    • 3
    • 关于注释
    - Python语言
    	# 注释
        """ 注释 """
    - HTML
    	
        
    - CSS注释
    	/* 注释 */
        
    - JavaScript
    	// 注释
        /* 注释 */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    1.8 Django

    • 安装
    pip install django
    
    • 1
    • 创建Django项目
    >>>django-admin  startproject  项目名
    
    • 1
    • 创建APP
    >>>cd 项目目录
    >>>python manange.py startapp app名称
    
    • 1
    • 2
    • 注册app
    - 不注册,models.py生成数据库表行为不执行。
    - 不注册,模板文件、静态文件,不回去app目录下找。
    
    • 1
    • 2
    • static目录,静态文件目录
    • templates目录,模板文件目录(HTML)
    • 表结构设计 app01/modes.py下执行
    from django.db import models
    
    class UserInfo(models.Model):
        v1 = models.CharField(max_length=32)
        ...
        ..
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • urls.py 中编写路由。
    from django.urls import path,re_path
    from app01 import admin
    
    
    urlpatterns = [
        path('admin/list/', admin.admin_list),
        path('admin//delete/', admin.admin_delete),
        re_path('admin/(?P\d+)/delete/', admin.admin_delete)
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 视图函数
    def admin_list(request):
        k1 = request.POST.get("k1")
        
        ... 业务处理
        
        return 数据
    
    - 默认参数request,包含请求相关的所有数据。
    	request.method
        request.GET
        request.POST
        request.FILES,上传文件。
        request.path_info,获取当前请求的URL
        	http://127.0.0.1:8000/depart/add/  ->    /depart/add/
                    
    - 返回值
    	return HttpResponse("字符串")
    	return JSONResponse( {"status":123,"data":[456,55,66,22,]} )
    		return JSONResponse( [11,22,33,44] ,safe=False)
    	return render(request,"xxx.html",{})
    	return redirect("http://127.0.0.1:8000/depart/add/")
    			return redirect("/depart/add/")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 数据库的ORM操作
    # 增加
    models..objects.create(name="武沛齐",age=19)
    models..objects.create(**{"name":"武沛齐","age":19})
    
    obj = models.(name="武沛齐",age=19)
    obj.save()
    
    obj_list = [
        models.(name="武沛齐",age=19),
        models.(name="武沛齐",age=19),
        models.(name="武沛齐",age=19),
        models.(name="武沛齐",age=19),
        models.(name="武沛齐",age=19)
        。。。
    ]
    models..objects.bulk_create(obj_list,batch_size=10)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • Form和ModelForm组件
    - 自动生成HTML标签
    - 对用户请求的数据进行校验
    	- 自动保存到数据库(ModelForm)
    - 错误信息
    
    • 1
    • 2
    • 3
    • 4
    • 关于POST提交CSRF认证
    <form method='post'>
        {% csrf_token %}
        ...
    form>
    
    • 1
    • 2
    • 3
    • 4


    如果想要免除csrf认证。

    • Cookie和Session
    cookie,本质上保存在浏览器端的键值对。 
    session,保存服务器端(django是将session默认存储在数据库中)
    
    def order_add(request):
        request.session['xx'] = 123
        
    def logout(request):
    	request.session.clear()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 中间件
    - 类 process_request / process_response
    - 注册中间件类
        MIDDLEWARE = [
            'django.middleware.security.SecurityMiddleware',
            'django.contrib.sessions.middleware.SessionMiddleware',
            'django.middleware.common.CommonMiddleware',
            'django.middleware.csrf.CsrfViewMiddleware',
            'django.contrib.auth.middleware.AuthenticationMiddleware',
            'django.contrib.messages.middleware.MessageMiddleware',
            'django.middleware.clickjacking.XFrameOptionsMiddleware',
            'app01.middleware.auth.AuthMiddleware',
        ]
    - django请求到达之后,自动会执行相应的方法。
    
    - process_request
    	- 没有返回值或返回None,继续向后执行。
    	- 返回redirect/render/HttpResponse/JsonReponse,拦截请求不再继续向后之后。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 图片验证码
    pip install pillow
    
    • 1
    • 分页组件
    开发时候会用。
    
    • 1

    2.关于文件上传

    2.1 基本操作

    <form method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <input type="text" name="username">
        <input type="file" name="avatar">
        <input type="submit" value="提交">
    form>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    from django.shortcuts import render, HttpResponse
    
    
    def upload_list(request):
        if request.method == "GET":
            return render(request, 'upload_list.html')
    
        # # 'username': ['big666']
        # print(request.POST)  # 请求体中数据
        # # {'avatar': []}>
        # print(request.FILES)  # 请求发过来的文件 {}
    
        file_object = request.FILES.get("avatar")
        # print(file_object.name)  # 文件名:WX20211117-222041@2x.png
    
        f = open(file_object.name, mode='wb')
        for chunk in file_object.chunks():
            f.write(chunk)
        f.close()
        return HttpResponse("...")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    案例:批量上传数据

    <form method="post" enctype="multipart/form-data" action="/depart/multi/">
        {% csrf_token %}
        <div class="form-group">
            <input type="file" name="exc">
        div>
        <input type="submit" value="上传" class="btn btn-info btn-sm">
    form>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    def depart_multi(request):
        """ 批量删除(Excel文件)"""
        from openpyxl import load_workbook
    
        # 1.获取用户上传的文件对象
        file_object = request.FILES.get("exc")
    
        # 2.对象传递给openpyxl,由openpyxl读取文件的内容
        wb = load_workbook(file_object)
        sheet = wb.worksheets[0]
    
        # 3.循环获取每一行数据
        for row in sheet.iter_rows(min_row=2):
            text = row[0].value
            exists = models.Department.objects.filter(title=text).exists()
            if not exists:
                models.Department.objects.create(title=text)
    
        return redirect('/depart/list/')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    案例:混合数据(Form)

    提交页面时:用户输入数据 + 文件(输入不能为空、报错)。

    • Form生成HTML标签:type=file
    • 表单的验证
    • form.cleaned_data 获取 数据 + 文件对象
    {% extends 'layout.html' %}
    
    
    {% block content %}
    
        <div class="container">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title"> {{ title }} h3>
                div>
                <div class="panel-body">
                    <form method="post" enctype="multipart/form-data" novalidate >
                        {% csrf_token %}
    
                        {% for field in form %}
                            <div class="form-group">
                                <label>{{ field.label }}label>
                                {{ field }}
                                <span style="color: red;">{{ field.errors.0 }}span>
                            div>
                        {% endfor %}
    
                        <button type="submit" class="btn btn-primary">提 交button>
                    form>
                div>
            div>
        div>
    
    {% endblock %}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    from django import forms
    from app01.utils.bootstrap import BootStrapForm
    
    
    class UpForm(BootStrapForm):
        bootstrap_exclude_fields = ['img']
    
        name = forms.CharField(label="姓名")
        age = forms.IntegerField(label="年龄")
        img = forms.FileField(label="头像")
    
    
    def upload_form(request):
        title = "Form上传"
        if request.method == "GET":
            form = UpForm()
            return render(request, 'upload_form.html', {"form": form, "title": title})
    
        form = UpForm(data=request.POST, files=request.FILES)
        if form.is_valid():
            # {'name': '武沛齐', 'age': 123, 'img': }
            # 1.读取图片内容,写入到文件夹中并获取文件的路径。
            image_object = form.cleaned_data.get("img")
    
            # file_path = "app01/static/img/{}".format(image_object.name)
            db_file_path = os.path.join("static", "img", image_object.name)
    
            file_path = os.path.join("app01", db_file_path)
            f = open(file_path, mode='wb')
            for chunk in image_object.chunks():
                f.write(chunk)
            f.close()
    
            # 2.将图片文件路径写入到数据库
            models.Boss.objects.create(
                name=form.cleaned_data['name'],
                age=form.cleaned_data['age'],
                img=db_file_path,
            )
            return HttpResponse("...")
        return render(request, 'upload_form.html', {"form": form, "title": title})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    注意:就目前而言,所有的静态文件都只能放在static目录。

    在django的开发过程中两个特殊的文件夹:

    • static,存放静态文件的路径,包括:CSS、JS、项目图片。
    • media,用户上传的数据的目录。

    2.2 启用media

    在urls.py中进行配置:

    from django.urls import path, re_path
    from django.views.static import serve
    from django.conf import settings
    
    urlpatterns = [
    	re_path(r'^media/(?P.*)$', serve, {'document_root': settings.MEDIA_ROOT}, name='media'),
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在settings.py中进行配置:

    import os
    
    MEDIA_ROOT = os.path.join(BASE_DIR, "media")
    MEDIA_URL = "/media/"
    
    • 1
    • 2
    • 3
    • 4

    在浏览器上访问:

    案例:混合数据(form)

    from django import forms
    from app01.utils.bootstrap import BootStrapForm
    
    
    class UpForm(BootStrapForm):
        bootstrap_exclude_fields = ['img']
    
        name = forms.CharField(label="姓名")
        age = forms.IntegerField(label="年龄")
        img = forms.FileField(label="头像")
    
    
    def upload_form(request):
        title = "Form上传"
        if request.method == "GET":
            form = UpForm()
            return render(request, 'upload_form.html', {"form": form, "title": title})
    
        form = UpForm(data=request.POST, files=request.FILES)
        if form.is_valid():
            # {'name': '武沛齐', 'age': 123, 'img': }
            # 1.读取图片内容,写入到文件夹中并获取文件的路径。
            image_object = form.cleaned_data.get("img")
    
            # media_path = os.path.join(settings.MEDIA_ROOT, image_object.name)
            media_path = os.path.join("media", image_object.name)
            f = open(media_path, mode='wb')
            for chunk in image_object.chunks():
                f.write(chunk)
            f.close()
    
            # 2.将图片文件路径写入到数据库
            models.Boss.objects.create(
                name=form.cleaned_data['name'],
                age=form.cleaned_data['age'],
                img=media_path,
            )
            return HttpResponse("...")
        return render(request, 'upload_form.html', {"form": form, "title": title})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    案例:混合数据(ModalForm)

    models.py
    class City(models.Model):
        """ 城市 """
        name = models.CharField(verbose_name="名称", max_length=32)
        count = models.IntegerField(verbose_name="人口")
    
        # 本质上数据库也是CharField,自动保存数据。
        img = models.FileField(verbose_name="Logo", max_length=128, upload_to='city/')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    定义ModelForm
    from app01.utils.bootstrap import BootStrapModelForm
    
    
    class UpModelForm(BootStrapModelForm):
        bootstrap_exclude_fields = ['img']
    
        class Meta:
            model = models.City
            fields = "__all__"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    视图
    def upload_modal_form(request):
        """ 上传文件和数据(modelForm)"""
        title = "ModelForm上传文件"
        if request.method == "GET":
            form = UpModelForm()
            return render(request, 'upload_form.html', {"form": form, 'title': title})
    
        form = UpModelForm(data=request.POST, files=request.FILES)
        if form.is_valid():
            # 对于文件:自动保存;
            # 字段 + 上传路径写入到数据库
            form.save()
            
            return HttpResponse("成功")
        return render(request, 'upload_form.html', {"form": form, 'title': title})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    小结

    • 自己手动去写
    file_object = request.FILES.get("exc")
    ...
    
    • 1
    • 2
    • Form组件(表单验证)
    request.POST
    file_object = request.FILES.get("exc")
    
    具体文件操作还是手动自己做。
    
    • 1
    • 2
    • 3
    • 4
    • ModelForm(表单验证 + 自动保存数据库 + 自动保存文件)
    - Media文件夹
    - Models.py定义类文件要
    	img = models.FileField(verbose_name="Logo", max_length=128, upload_to='city/')
    
    • 1
    • 2
    • 3

    总结

    关于django的开发知识点,更多的案例:

    • Python基础(课件 https://gitee.com/wupeiqi/python_course)
    https://www.bilibili.com/video/BV1m54y1r7zE
    
    • 1
    • 并发编程(进程线程协程)
    https://www.bilibili.com/video/BV1Ev411G7i3?spm_id_from=333.999.0.0
    
    # 不建议小白学(协程)
    https://www.bilibili.com/video/BV1NA411g7yf?spm_id_from=333.999.0.0
    
    • 1
    • 2
    • 3
    • 4
    • MySQL数据库
    # 2021最新推荐
    https://www.bilibili.com/video/BV15R4y1b7y9?spm_id_from=333.999.0.0
        
    # 2017年
    https://www.bilibili.com/video/BV1DE411n7fU?
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 前端开发
    https://www.bilibili.com/video/BV1QE411j7bV?spm_id_from=333.999.0.0
    
    • 1
    • django开发知识点
    https://www.bilibili.com/video/BV1zE411x7LG
    https://www.bilibili.com/video/BV1JE411V7xk
    
    • 1
    • 2
    • 项目开发
    任务管理平台:https://www.bilibili.com/video/BV1uA411b77M
    
    • 1
    • 进阶项目(增删改查、权限)
    https://space.bilibili.com/283478842/channel/detail?cid=91596&ctype=0
    
    • 1
    • 前后端分离的项目: django + drf框架 + vue.js
    - Django
    - drf框架
    	- https://www.bilibili.com/video/BV1ZE411j7RK
    
    • 1
    • 2
    • 3
    • git 版本控制和协同开发 + 任务管理平台
    https://www.bilibili.com/video/BV19E411f76x?spm_id_from=333.999.0.0
    
    • 1
    • 微信小程序 + Django + drf框架编写
    https://www.bilibili.com/video/BV1jC4y1s7QD?spm_id_from=333.999.0.0
    
    • 1
  • 相关阅读:
    Azure vs. AssemblyAI:深度解析语音转文本服务的对决
    【每天学习一点新知识】Windows下命令行echo如何换行实现多行文本输出
    【Java 进阶篇】使用 Java 和 Jsoup 进行 XML 处理
    神经网络结构搜索
    vue-template-admin项目的主题样式设置
    【FPGA+sin】基于DDS(直接数字合成)的正弦信号发生器模块FPGA实现
    JSP在Scriptlet中编写java代码的形式
    【Pytorch】Visualization of Feature Maps(1)
    基于JAVA SpringBoot的网课管理系统设计与实现源码
    离散化,矩阵快速幂,广义矩阵乘法
  • 原文地址:https://blog.csdn.net/Jasminexjf/article/details/127459536