当前位置:   article > 正文

python-web开发[20]之开发小结_python网页前端开发实训总结

python网页前端开发实训总结


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表单
	<form method="post" action="地址"> 
		<input ....
		
		<input type='submit' ... />
	</form>
	
- 关于a标签
	<a href="www.baidu.com">百度</a>   超链接去跳转。
	做锚点
        <a href="#m1">第一章</a>
        <a href="#m2">第二章</a>
        <div id="m1" style="height: 1000px;">第一章 谢新雪</div>
        <div id="m2" style="height: 1000px;">第二章 单独的</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • CSS
- 位置
	- 标签 <div style="xxx">
	- style代码块
		<style>
			div { }
			#v1 { }
			.v2 {}
		</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()            <div id='x1'>dd</div>
	$("#x1").text("xxx")       <div id='x1'>xxx</div>
	
	$("#x1").val()             <input id='x1' />
	$("#x1").val("xxx")        <input id='x1' />
	
	$("#x1").attr("uu")           <div id='x1' uu="123">dd</div>
	$("#x1").attr("uu","999")     <div id='x1' uu="999">dd</div>
	
	$("#x1").empty()          <div id='x1'>dd</div>  - 清空内容
	$("#x1").remove()         <div id='x1'>dd</div>  - 整个标签删除
  • 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/<int:nid>/delete/', admin.admin_delete),
    re_path('admin/(?P<nid>\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': [<InMemoryUploadedFile: 图片 1.png (image/png)>]}>
    # 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': <InMemoryUploadedFile: 图片 1.png (image/png)>}
        # 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<path>.*)$', 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': <InMemoryUploadedFile: 图片 1.png (image/png)>}
        # 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
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/560503
推荐阅读
相关标签
  

闽ICP备14008679号