巩固复习(Django最基础的部分_具体查看官方文档)

Django学习路1
1.脚本不能随便运行,没准 linux 运行完就上不去了
2.pip 在 linux 上 写 pip3
    同理 python 写为 python3
3.在 pycharm 上安装库之后,在命令提示符中依旧需要安装
    才能在终端进行使用
4.在虚拟环境下安装 uwsgi
5.升级 django 到2.0版本解决  pip3 install django==2.0.4
    ImportError: cannot import name 'path'
6.python3 manage.py migrate 解决
    You have 14 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
7.python3 manage.py runserver
    打开网址就可以运行成功了

使用 1.11.14 版本较多,推荐使用

Django学习路2
1.导入 Django 工程时 在 manage.py 上一级目录导入
2.Add local 本地    Add Remote 远端
3.BASE_DIR 项目所在目录的绝对路径
4.SECRET_KEY  相当于密钥
5.项目开发后->进行测试->演示环境->上线生产环境
6.DEBUG = True 调试模式
7.ALLOWED_HOSTS = [] 运行访问的主机,写 ip 地址
    ALLOWED_HOSTS = ["*"] 表示所有人访问
8.INSTALLED_APPS Django 内置应用
9.MIDDLEWARE 中间件,面向切面编程
10.ROOT_URLCONF 根路由
11.TEMPLATES 模板
12.WSGI_APPLICATION 部署应用
13.DATABASES 数据库
14.db.sqlite3 轻量级数据库,安卓 ios 内都具备
    不用于企业开发,和 mysql 类似
15.AUTH_PASSWORD_VALIDATORS 认证密码验证器
16.LANGUAGE_CODE 语言编码 英文 'en-us'
    中文 LANGUAGE_CODE = 'zh-hans'
17.TIME_ZONE 统一协调时间  'Asia/Shanghai'

Django学习路3
1.打开 Data Source
alt insert 打开 Data Source 找到 db.sqlite3 确定
Download 下载后 TestConnection 测试是否成功
2.项目下的 urls.py 文件
    urlpatterns 匹配网页集合
    写法 url(正则,views.函数)
     url(r'函数名/',views.函数) 最好是斜线结尾
      views 来自创建的 app 中,需要导入
       views.py 内定义函数 def 函数名(request):pass
        HttpResponse("内容") 进行响应
         内容可以是 HTML 代码(a标签,h1标题等等)
        render(request,"模板名字")
         render(request,"index.html")
          直接写文件名.html
3.进行访问 127.0.0.1:8000/函数名
4.templates 包含 HTML 文件
    显示数据 -> 在 urls.py 中添加
     url(r"函数名/",views.函数名)
5.让项目和创建的 App 连接
    在项目的 settings.py 文件的 INSTALLED_APPS 中添加 创建的 APP 名字
    例:INSTALLED_APPS = ['...','...','App']
6.SyntaxError: Generator expression must be parenthesized
打开 ~/HanyProject/venv/lib/python3.7/site-packages/django/contrib/admin 的 widgets.py 文件 到 151 行 将params.items() 后面的逗号去掉
7.升级 Django 到 2.x 版本
8.将 templates 加入到 settings 的 TEMPLATES 中 的 'DIRS''DIRS': [os.path.join(BASE_DIR, 'templates')]
9.出现错误先看日志文件

urls.py 文件


from django.contrib import admin
from django.urls import path

from Hanyapp import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path(r'sayHello/',views.sayHello),
    path(r'goBaiDu/',views.goBaiDu),
    path(r'index/',views.index)
]



views.py


from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.

def sayHello(request):
    return HttpResponse("<h3> 你好,世界 <h3>")

def goBaiDu(request):
    return HttpResponse("<a href = 'www.baidu.com'>百度</a>")

def index(request):
    return render(request,'index.html')


settings.py


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'Hanyapp'
]

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]


index.html


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
    用户名:<input type="text" placeholder="请输入用户名">
    密码:<input type="password">
</body>
</html>

Django坑_01

python manage.py runserver 运行出错
hostname, aliases, ipaddrs = gethostbyaddr(name)
UnicodeDecodeError: 'utf-8'

解决:
将计算机的名字改为英文,重新启动即可

 Django创建简单数据库

在 创建好的 app 目录下的 models.py 中,编写创建 数据库表的限制条件

class Student(models.Model):
    s_name = models.CharField(max_length=16)
    s_age = models.IntegerField(default=1)



在控制台编写如下语句

生成迁移文件
python manage.py makemigrations

执行迁移
python manage.py migrate

Django学习路4_数据库添加元素,读取及显示到网页上

在 views 中实现对数据库的添加和读取数据库


添加数据

对象 = models 中创建的类名()
对象.列名 = '字段值' 
对象.save() 进行保存
return HttpResponse('提示信息')


def add_student(request):
    stu = Student()
    stu.s_name = 'Hany_%d'%(random.randrange(10))
    stu.save()
    return HttpResponse("添加成功,添加的姓名为 %s"%(stu.s_name))

在 urls 中的 urlpatterns 中进行注册

url(r'addstu',views.add_student),


读取数据

对象 = models 中的类名.objects.all()
来获取objects 的接口

创建 context (字典对象)传递给 templates 中的 html 文档
context 的键是html 中需要使用的,值是需要显示的
context 是 from django.shortcuts import render 函数的参数
context = {
  '':值,
  '键2':值2
}


def get_student(request):

    stus = Student.objects.all()
    # 获取所有学生,objects 操作的入口
    context = {
        'hobby':'使用 Python 学 Django !',
        'stus':stus
    }
    # context 是一个字典,用来与 html 代码进行关联
    return render(request,'stu_list.html',context = context)


注:stu_list.html 是在 templates 中创建的 stu_list.html 文档


在 HTML 代码中显示

使用 {{view.py 函数中传递过来的 context 参数的键}} 即可访问
如果需要显示全部的数据,需要进行遍历
for 循环
{{% for 对象 in 键%}}
<标签名>{{对象.表的列名}}</标签名>
{{endfor}}


注:表的列名:models 的类中定义的属性


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>StudentList</title>
</head>
<body>
<h2>学生表</h2>
<h3> {{hobby}}</h3>

<h1>学生名单</h1>
<ul>
    {% for stu in stus %}
    <li>{{ stu.s_name }}</li>
    {% endfor  %}
</ul>
</body>
</html>

Django学习路5_更新和删除数据库表中元素

查找所有的元素
Student.objects.all()

查找单个元素
Student.objects.get(主键=值)
    主键 pk = xxx

更新数据库数据后进行保存
stu.save()

删除数据库表中的行
stu.delete()


需要注意的点:
update_student 函数和 delete_student 函数 返回值里面没有 request


def update_student(request):
    stu = Student.objects.get(pk = 2)
    # pk 主键值
    stu.s_name = 'Jack'
    stu.save()
    return HttpResponse("更新成功!")

def delete_student(request):
    stu = Student.objects.get(pk = 3)
    stu.delete( )
    return HttpResponse("删除成功")


urls.py 需要更新的内容    
  url(r'updatestu',views.update_student),
  url(r'deletestu',views.delete_student)

关于更新和存储的区别:
如果主键存在则为 更新表中元素
如果主键不存在则为 存储该元素

Django学习路6_修改数据库为 mysql ,创建mysql及进行迁徙

在项目的 settings 中修改 
DATABASES = {
    'default': {
        # 'ENGINE': 'django.db.backends.sqlite3',
        # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'ENGINE':'django.db.backends.mysql',
        'NAME':'Hany_mysql',
        'USER':'root',
        'PASSWORD':'root',
    #     mysql 位置
        'HOST':'127.0.0.1',
        'POST':'3306' #可以进行修改,避免攻击
    }
}


创建数据库

create database Hany_mysql charset=utf8;

在 pycharm 中创建一个 mysql 数据库
选择加号,选择 mysql

选择 Download 后点击 Test Connection


进行迁徙到 MySQL 数据库中
python manage.py migrate

注:如果出现缺失 MySQLdb 则需要进行安装这个第三方库

解决方案:
在 项目根目录下的 __init__.py 文件中 输入

import pymysql
pymysql.install_as_MySQLdb()
# 伪装成 MySQLdb

Django学习路7_注册app到能够在页面上显示app网页内容

在根目录下创建一个 app3 

创建一个 urls.py 
在 urls.py 中添加 urlpatterns 列表
容纳需要显示在页面上的函数

from django.conf.urls import url
from app3 import views

urlpatterns = [
    url(r'index',views.index)
]

注:
r'在网页上的函数名',views.py 中的函数名

在 views.py 中创建刚刚创建好的 index 函数
注: views.函数名 , 函数名是什么,这里的函数就创建什么名字

from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.
from django.template import loader


def index(request):
    three_index = loader.get_template('app3_index.html')
    result = three_index.render()
    print(result)
    return HttpResponse(result)

注:
loader.get_template 获取模板
three_index.render() 渲染为 html 文档

模板在 templates 中进行创建

在 app3 目录下,创建 templates 文件夹,存放 html 文档

app3_index.html

注:
文档名字随意,但是模板文件夹名字一定是 templates

app3_index.html 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>App3 index</title>
</head>
<body>
<h2>加油</h2>
</body>
</html>



在项目的 settings 中的 INSTALLED_APPS 列表中,添加 app3

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app.apps.AppConfig',
    'app2.apps.App2Config',
    'app3.apps.App3Config'
]

注:
也可以写为 'app3'


在 项目的 urls.py 中导入 app3 在页面上进行显示

from django.contrib import admin
from django.urls import path, include

from app import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path(r'hello',views.hello),
    path(r'index',views.index),
    path(r'home',views.home),
    path(r'app2',include('app2.urls')),
#     导入一组数据,使用 include
    path(r'app3',include('app3.urls'))
]

注:
使用 include('app名字.urls') 可以导入整个 app 包

扩展:
 app3 下的 apps.py 内容


from django.apps import AppConfig

class App3Config(AppConfig):
    name = 'app3'

运行:
python manage.py runserver

输入
http://127.0.0.1:8000/app名字/页面显示的名字

 
http://127.0.0.1:8000/app3/index

 

以上为添加到表中的元素

学生查询班级名字


在views.py 中添加函数方法,让学生获取班级姓名
此处应该注意数据库表 models.py 中的设计,使用的是类中定义的属性

def get_grade(request):
    # 通过学生 -> 班级
    stu = Student.objects.get(pk = 1)
    # 获取学生
    grade = stu.s_grade
    # 获取学生所在的班级
    return HttpResponse("Grade: %s"%(grade.g_name))
    # 获取班级的名字

注:
pk 是主键的意思
. 后面的名字都是自己设置的 类中的属性名


在 urls 中添加 get_grade  刚刚创建的函数

urlpatterns = [
    url(r'index',views.index),
    url(r'getgrade',views.get_grade)
]


运行后,结果如下

班级查询学生名字

在 views.py 中添加 对应的获取函数
函数名:get_students

def get_students(request):
    # 通过班级获取学生信息
    grade = Grade.objects.get(pk = 1)
    # 获取学生集合
    stus = grade.student_set.all()
    context = {
        # 添加到字典的值中
        'students':stus
    }
    return render(request,'students_list.html',context = context)
    # 使用 render 显示网页

注:
1.获取全部 grade.student_set.all() 学生信息
2.将获取到的信息存入到 context 的值中,才会在网页里进行遍历
    这里的键名,是网页中遍历的可迭代对象
3.使用 render 网页才会被渲染出来


在 templates 中添加 html 文档
students_list.html

<h3>
    {% for stu in students %}
    <li> {{ stu.s_name }}</li>
    {% endfor %}
</h3>

注:
1.使用 for 循环对传入的 context 参数进行遍历
2.使用 {% 语句 %} 的格式写入 python 代码
3.{{endfor}} 在结尾后


在 urls.py 中添加获取学生的函数

urlpatterns = [
    url(r'index',views.index),
    url(r'getgrade',views.get_grade),
    url(r'getstudent',views.get_students)
]


运行结果

 Django学习路9_流程复习

https://www.cnblogs.com/hany-postq473111315/p/12856419.html

Django学习路10_创建一个新的数据库,指定列名并修改表名
在 models.py 中添加

from django.db import models

# Create your models here.

class Person(models.Model):
    # 伪装成 models
    p_name = models.CharField(max_length=16,unique=True,db_column='name')
    # unique  设置为唯一
    # db_column 列名

    p_age = models.IntegerField(default=18,db_column='age')
    # default 设置默认值
    # False 代表男,True 代表女
    p_sex = models.BooleanField(default=False,db_column='sex')

    class Meta:
        db_table = 'People'
        # 修改表名


unique 设置为唯一的
db_column 指定列名
default 设置默认值

Meta 加入元信息 
db_table 指定表名


当存在 布尔类型时 数据库表中表示为 TINYINT(1)  节省空间

default 只有当存入数据时,才会进行使用

Django学习路11_向数据库中添加 和 获取指定条件数据
在 views.py 中添加函数 向数据库中添加数据

def add_persons(request):

    for i in range(15):
        person = Person()
        flag = random.randrange(100)
        person.p_name = "Hany_ %d"%(i)
        person.p_age = flag
        person.p_sex = flag%2
        person.save()
    return HttpResponse("批量添加成功")

注: 
使用随机数,进行添加数据(目前还是静态数据)
添加表中的元素属性值
save 进行保存
在使用 random 之前先进性导入


http://127.0.0.1:8000/app4/addpersons


添加一条数据

def add_person(request):
    person = Person.objects.create(p_name='Yizhan')
    # 使用 objects.create 进行创建一条数据
    person.save()
    return HttpResponse("%s 创建成功"%(person.p_name))

注:
使用 create 方法进行创建


 

 

获取数据

def get_persons(request):
    # persons = Person.objects.filter(p_age__gt=30)
    '''age 大于 30 的 '''
    # persons = Person.objects.filter(p_age__gt=30).filter(p_age__lt=80)
    '''.filter .filter 表示且'''
    persons = Person.objects.exclude(p_age__lt=30).exclude(p_age__gt=80)
    '''age 大于 30 的 , 小于 80 的,exclude 除了,不包含的意思 '''
    print(type(persons))
    '''<class 'django.db.models.query.QuerySet'> 结果集类型'''
    context = {
        'persons':persons
    #     传递到前端代码中
    }
    return render(request,'person_list.html',context = context)

注: 
.filter(表示包含的条件)
.filter(表示包含的条件).filter(表示包含的条件)  表示两个条件都需要满足,且

获取到的数据都是 QuerySet 类型,放入到值中,使用网页进行遍历
这里使用的是 render ,不是 HttpResponse

p_age__gt 表示大于
p_age__lt 表示小于



获取一条数据
objects.get(条件)

first() 返回查询集中的第一个对象

last() 返回查询集中的最后一个对象

count() 返回当前查询集中的对象个数

exists() 判断查询集中是否有数据,返回 True 和 False
True 表示有数据

def get_person(request):
    person = Person.objects.get(p_age = 48)
    context = {
        'person':person
    }
    return render(request,'person_one.html',context = context)

注: 
如果没有查询到数据,则会报 500 服务器异常
DoesNotExist 异常

如果查询到的对象多于一个,返回两个对象也会报错
MultiObjectsReturned 异常


 

 

templates 中person_list.html 内容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h2>Person 大于 30 的 , 小于 80 的 :</h2>
<h4>
    {% for person in persons %}
    <li>
        姓名:{{ person.p_name }} 年龄{{ person.p_age }}
    </li>
    {% endfor %}
</h4>
</body>
</html>

注:
在 for 循环的时候两边有 {%    %}
正常单个语句时,使用的是 {{ 属性}}
最后要加上 {% endfor %}

此处的 属性为数据库表中的元素


不要忘了的点:

urlpatterns = [
    url(r'addpersons',views.add_persons),
    url(r'getpersons',views.get_persons),
    url(r'addperson',views.add_person)
]

在 urls.py 中 ,进行注册


启动命令

python manage.py runserver

 

使用类方法创建单个对象示例:

在 models.py 中自定义类方法 create 进行创建

    @classmethod
    def create(cls,p_name,p_age = 100,p_sex = True):
        # 自定义方法进行创建对象,可以包含表达式
        return cls(p_name = p_name,p_age = p_age,p_sex = p_sex)

views.py 中 add_person 函数

def add_person(request):
    person = Person.create('Lao')
    person.save()
    return HttpResponse("创建成功")

Django学习路12_objects 方法(all,filter,exclude,order by,values)
Person.objects.all()
获取全部数据

def get_persons(request):

    persons = Person.objects.all()
    # 获取全部数据

    context = {
        'persons':persons
    #     传递到前端代码中
    }
    return render(request,'person_list.html',context = context)
使用 order_by  默认为 id 进行排序

def get_persons(request):

    persons = Person.objects.all().order_by("p_age")
    # 获取全部数据

    context = {
        'persons':persons
    #     传递到前端代码中
    }
    return render(request,'person_list.html',context = context)

注:
order_by(" 列名 ") 列名写在引号中
使用 filter 对表中元素进行筛选
符合条件的留下,  .filter(条件).filter(条件) 表示 两个条件都要满足

def get_persons(request):
    persons = Person.objects.filter(p_age__gt=30)
    '''age 大于 30 的 '''

    context = {
        'persons':persons
    #     传递到前端代码中
    }
    return render(request,'person_list.html',context = context)

注:
filter 将满足条件的保存下来
gt 表示 大于 
lt 表示小于
使用两个 filter 表示 且

def get_persons(request):
    persons = Person.objects.filter(p_age__gt=30).filter(p_age__lt=80)
    '''.filter .filter 表示且'''
    # persons = Person.objects.filter(p_age__gt=30)
    '''age 大于 30 的 '''

    context = {
        'persons':persons
    #     传递到前端代码中
    }
    return render(request,'person_list.html',context = context)
exclude 表示不包含的,在条件之外的数据

def get_persons(request):
    persons = Person.objects.exclude(p_age__lt=30)
    '''age 大于 30 的'''
    context = {
        'persons':persons
    #     传递到前端代码中
    }
    return render(request,'person_list.html',context = context)

注:
条件 在这里是 p_age__lt=30 即表示 小于 30
Person.objects.exclude(条件).exclude(条件)
表示 两个条件都不满足的数据

def get_persons(request):
    persons = Person.objects.exclude(p_age__lt=30).exclude(p_age__gt=80)
    '''age 大于 30 的 , 小于 80 的,exclude 除了,不包含的意思 '''
    context = {
        'persons':persons
    #     传递到前端代码中
    }
    return render(request,'person_list.html',context = context)
values 
获取 <QuerySet [{表中行元素},{表中行元素}, ....,{表中行元素}]>

很类似于 json 数据

def get_persons(request):
    persons = Person.objects.exclude(p_age__lt=30).exclude(p_age__gt=80)
    '''age 大于 30 的 , 小于 80 的,exclude 除了,不包含的意思 '''
    print(persons.values())
    context = {
        'persons':persons
    #     传递到前端代码中
    }
    return render(request,'person_list.html',context = context)

注:
只是添加了 persons.values() 
获取到的数据为 

<QuerySet [{'id': 2, 'p_name': 'Hany_ 1', 'p_age': 31, 'p_sex': True}, {'id': 5, 'p_name': 'Hany_ 4', 'p
_age': 78, 'p_sex': False}, {'id': 7, 'p_name': 'Hany_ 6', 'p_age': 47, 'p_sex': True}, {'id': 12, 'p_na
me': 'Hany_ 11', 'p_age': 77, 'p_sex': True}, {'id': 13, 'p_name': 'Hany_ 12', 'p_age': 48, 'p_sex': Fal
se}]>

Django学习路13_创建用户登录,判断数据库中账号名密码是否正确

在 models.py 中设置数据库表的信息

from django.db import models

# Create your models here.

class User(models.Model):
    u_name = models.CharField(max_length=16,unique=True)
    # 用户名唯一
    u_password = models.CharField(max_length=256)
    # 设置密码


产生迁移文件,进行迁移

python manage.py makemigrations 

python manage.py migrate


urls.py 产生路由

from django.conf.urls import url

from app5 import views

urlpatterns = [
    url(r'getuser',views.get_user)
]


在 views.py 中编写函数

from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.
from app5.models import User

def get_user(request):
    username = "qqq"
    # 用户输入的用户名
    password = "000"
    # 密码
    users = User.objects.filter(u_name = username)
    # 查看 User 表有没有 username
    if users.count():
    # .count 也可以写为 .exists,直接判断是否存在
    #     有就是 1  , 没有就是 0
    # user 用户存在
        user = users.first()
    #     取数据  last() 也可以
        if user.u_password == password:
            print("登陆成功")
        else:
            print("密码错误")
    else:
        print("用户名不存在")
    return HttpResponse("获取成功")

注:
静态的设置了账号密码,根据数据库的 user 表查看是否存在该数据
.count() 和 .exists()  都可以判断是否存在该数据
先验证用户名是否存在,再判断密码是否存在

Django学习路14_获取数据库中用户名字并展示,获取指定条数
在 views.py 中添加 获取函数
注:此时获取的是全部用户的信息

def get_users(request):
    users = User.objects.all()
    context = {
        'users':users
    }

    return render(request,'user_list.html',context = context)

注:
如果使用切片,则在 all() 后面 [ 起始:结束]  
这里需要注意的是  QueueSet 类型是 左闭右闭 的
如果这里写的对,没显示数据,那就是 user_list.html 有问题


在 urls.py 中 进行注册

from django.conf.urls import url

from app5 import views

urlpatterns = [
    url(r'getuser/',views.get_user),
    url(r'getusers/',views.get_users)
]


在 数据库表中添加一些用户密码

 

app5 下的 templates 文件夹下 创建 user_list.html 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<ul>
    {% for user in users %}
    <li>{{ user.u_name }}</li>
    {% endfor %}
</ul>
</body>
</html>

注:
for 循环写在 <ul> 标签下,不是 <hn>标签
<li> 标签里面写内容,为了整齐,形成有序列表 



获取指定条数数据

第二条数据 到 第五条数据

def get_users(request):
    users = User.objects.all()[1:5]

    context = {
        'users':users
    }

    return render(request,'user_list.html',context = context)


注:
切片是左闭右闭的
[起始位置:结束位置]

以前的 字符串等等,都是左闭右开的!!

Django坑_02

在创建订单的时候会创建一个对应的日期

查询数据库表的时候,查询年的话可以正常实现 

但是如果单独查询某一个月的话,可能会出错  

在 Django 中月份可能会使用 Django 中定义的时区 

将 项目 settings.py 中的  USE_TZ = True 改为 False

Django学习路15_创建一个订单信息,并查询2020年9月的信息都有哪些
复制代码
在 app5.models.py 中添加一个 Order 表

class Order(models.Model):
    o_num = models.CharField(max_length= 16 ,unique=True)
    # 创建一个订单号,设置为 唯一
    o_time = models.DateTimeField(auto_now_add=True)
    # 创建一个时间,当对象进行保存时即可生成订单时间

注:
auto_now_add 当进行 save() 保存时,就会自动进行设置时间
复制代码

产生迁移 -> 进行迁移

 

插入数据 如下所示


修改后的数据


复制代码
在 urls 中添加获取订单的函数 getorders

urlpatterns = [
    url(r'getuser/',views.get_user),
    url(r'getusers/',views.get_users),
    url(r'getorders',views.getorders)
]
复制代码
复制代码
在 views.py 中添加获取 2020年 的函数

def getorders(request):
orders = Order.objects.filter(o_time__year= 2020)
context = {
'orders':orders
}
return render(request,'orders.html',context = context)
复制代码
复制代码
在 templates 的 orders.html 中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul>
    {% for order in orders %}
    <li>{{ order.o_num }}</li>
    {% endfor %}
</ul>
</body>
</html>
复制代码

复制代码
获取 9 月的信息

项目根目录的 settings.py 中的 USE_TZ = False 提前设置好

def getorders(request):
    orders = Order.objects.filter(o_time__month = 9)
    context = {
        'orders':orders
    }
    return render(request,'orders.html',context = context)
复制代码


Django学习路16_获取学生所在的班级名
在 urls.py 中先导入getgrades

from django.conf.urls import url

from app5 import views

urlpatterns = [
    url(r'getuser/',views.get_user),
    url(r'getusers/',views.get_users),
    url(r'getorder',views.getorders),
    url(r'getgrades',views.getgrades),
]
在 views.py 中编写 getgrades 函数

def getgrades(request):
    grades = Grade.objects.filter(student__s_name='qq')
    # 班级里包含名字为 qq 的
    for grade in grades:
        print(grade.g_name)

    return HttpResponse("获取成功")
此前的准备工作:创建数据库表 

class Grade(models.Model):
    g_name = models.CharField(max_length=16)

class Student(models.Model):
    s_name = models.CharField(max_length= 16)
    s_grade = models.ForeignKey(Grade,on_delete=True)
    # 设置班级外键

Django学习路17_聚合函数(Avg平均值,Count数量,Max最大,Min最小,Sum
使用方法:
类名.objects.aggregate(聚合函数名('表的列名'))

聚合函数名:
Avg 平均值

Count数量

Max 最大

Min 最小

Sum 求和

示例:
Student.objects.aggregate(Max('sage'))
创建消费者数据表 Customer

class Customer(models.Model):
    c_name = models.CharField(max_length = 16)
    # 消费者名字
    c_cost = models.IntegerField(default = 10)
    # 消费的金额
产生迁移文件
python manage.py makemigrations

进行迁移
python manage.py migrate
Max 示例

def getcostmax(request):
    cost_max = Customer.objects.aggregate(Max("c_cost"))
    print(cost_max)
    return HttpResponse("获取成功")
Min示例
def getcostmin(request):
    cost_min = Customer.objects.aggregate(Min("c_cost"))
    print(cost_min)
    return HttpResponse("获取成功")

注:
不要忘记在 urls.py 中进行注册
Sum 示例

def getcostsum(request):
    cost_sum = Customer.objects.aggregate(Sum("c_cost"))
    print(cost_sum)
    return HttpResponse("获取成功")

Count 示例
def getcustomercount(request):
    customer_count = Customer.objects.aggregate(Count("c_name"))
    print(customer_count)
    return HttpResponse("获取成功")

注:
此时获取姓名即可,不用获取价格
Avg 示例
def getcostavg(request):
    cost_avg = Customer.objects.aggregate(Avg("c_cost"))
    print(cost_avg)
    return HttpResponse("获取成功")

导入的包

from django.db.models import Max, Min, Sum, Count, Avg
from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.
from app5.models import User, Order, Grade, Customer

Django学习路18_F对象和Q对象
F 对象:
可以使用模型的 A 属性和 B 属性进行比较
写法:
需要的数据对象 = 数据表(类名).objects.filter(列名__条件=F('列名2'))
需求: 查看男生数量比女生少 的公司名称
companies = Company.objects.filter(c_boy_num__lt=F('c_girl_num'))

F 对象支持算术运算

需求: 查看男生数量比女生少 15个的公司名称
companies = Company.objects.filter(c_boy_num__lt=F('c_girl_num')-15)
在 models.py 中创建数据表 Company

class Company(models.Model):
    c_name = models.CharField(max_length=16)
    # 公司名字
    c_girl_num = models.IntegerField(max_length=16)
    # 女生人数
    c_boy_num = models.IntegerField(max_length=16)
    # 男生人数
产生迁移文件
python manage.py makemigrations

进行迁移
python manage.py migrate
在 urls.py 中进行注册

需求:
查看 女生多于男生的公司名称

url(r'getgirlgtboy',views.getgirlgtboy)

views.py 中创建 getgirlgtboy 函数

def getgirlgtboy(request):
    companies = Company.objects.filter(c_girl_num__gt=F('c_boy_num'))
    for company in companies:
        # 进行遍历后查看公司名
        print(company.c_name)
    return HttpResponse("获取成功")

注:
F 导包 导入的是 
from django.db.models import F

F 对象使用 算数表达式

def getgirlgtboy(request):
    companies = Company.objects.filter(c_girl_num__lt=F('c_boy_num')-30)
    # 查看男生比女生多于 30 的
    for company in companies:
        # 进行遍历后查看公司名
        print(company.c_name)
    return HttpResponse("获取成功")

Q 对象
过滤器的方法中的参数 
常用于 组合条件

表名(models中创建的类) .objects.filter(Q(表中列名__条件=值))

示例:
Student.objects.filter(Q(sage_lt=25))

Q对象支持 | & ~ 

年龄大于等于 25 的
分析: 不小于 25
示例:
Student.objects.filter(~Q(sage_lt=25))
Q 对象可以对条件进行封装
封装后支持逻辑运算
与 & 或 |非 ~

在 urls.py 中进行注册

url(r'getgirlandboy',views.getgirlandboy)

在 models.py 中添加 对应的函数 getgirlandboy

def getgirlandboy(request):
    companies = Company.objects.filter(Q(c_boy_num__gt=90) & Q(c_girl_num__gt=80))
    # 男生大于 90 且 女生大于 80 的公司名称
    for company in companies:
        # 进行遍历后查看公司名
        print(company.c_name)
    return HttpResponse("获取成功")

注:
且  :  Q(条件) & Q(条件) 
取反 : ~Q  表示取反
或 :  Q(条件) | Q(条件)

Django学习路19_is_delete属性,重写类方法,显性隐性属性
如果在 创建数据表时,使用了 
objects =  models.Model() 
使隐形属性变为了 显性属性 
则 必须要自己定义一个 
    继承了 models.Model 类的类,实现 管理功能

如果一个属性一直都需要使用 
比如 is_delete 属性,判断 这条数据是否删除
is_delete 为 True 也就是 1 时,则表示删除了
删除了就不应该在数据库表中再次使用了
models.py 中新添加的数据表,及其继承类

class AnimalManage(models.Manager):
    # 父类先声明,继承的是 models.Manager 类,需要重写 filter 方法
    '''使用继承,重写原来类的方法,进行改进函数时,考虑类的继承'''
    def get_queryset(self):
        '''使 filter 自动具有保留 is_delete 为 0 的功能,is_delete 为 1 的自动过滤掉'''
        # return super(AnimalManage,self).get_queryset()
        # 对父类的方法进行修改,将 is_delete 为 0 的留下
        return super(AnimalManage,self).get_queryset().filter(is_delete = False)

    def create(self,a_name = "Pandas"):
        # 默认创建一个熊猫
        '''改写创建对象语句,使用子类完成操作'''
        animal = self.model()
        # 创建一个模型
        animal.a_name = a_name
        return animal


class Animal(models.Model):
    # 创建一个数据表为 Animal
    a_name = models.CharField(max_length=16)
    # 动物名字
    is_delete = models.BooleanField(default=False)
    # 设置是否删除数据,默认不删除,数据库中表示为 0

    objects = AnimalManage()
    # 设置管理者,objects 是什么名字
    # 类名.定义的名字.all()

添加到数据库表中的数据

其中 is_delete 为 1 的表示已经删除的数据

is_delete 是需要的数据

在 urls.py 中添加参数

url(r'getanimals',views.getanimals)

在 views.py 中添加 views. 后面的函数名

def getanimals(request):
    animals = Animal.objects.all()
    # 这里使用的是子类的实例化对象 objects
    context = {
        'animals':animals
    }
    '''
    animal = Animal.objects.create('动物名称')
    使用 子类中定义的方法进行创建
    '''

    return render(request,'Animals.html',context=context)

在 templates 中创建 render 函数中的 'xxx.html' 文件
此处 我的是 Animals.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>动物</title>
</head>
<body>
    <h2>动物列表</h2>
    <ul>
        {% for animal in animals %}
        <li>{{ animal.a_name }}</li>
        {% endfor %}
    </ul>
</body>
</html>

is_delete 为 1 的过滤掉了, 为 0 的保存了下来

Django学习路20_流程复习
https://www.cnblogs.com/hany-postq473111315/p/12881490.html

Django学习路21_views函数中定义字典及html中使用类实例对象的属性及方法
创建 app6  在项目的 settings 中进行注册
INSTALLED_APPS 里面添加 'app6.apps.App6Config'

在 app6 的models.py 中创建数据表

class Student(models.Model):
    s_name = models.CharField(max_length= 16)

进行迁移
python manage.py makemigrations 
python manage.py migrate 

在 views 中添加函数
from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.
from app6.models import Student


def hello(request):
    return HttpResponse("你好")

def index(request):
    # render 实质上也是返回 HttpResponse ,render 帮助把模板和context数据渲染成字符串
    '''
    temp = loader.get_template('index6.html')
    content = temp.render()
    return HttpResponse(content)
    两者等价
    return render(request,'index6.html')
    '''

    return render(request,'index6.html')

def getstudents(request):

    students = Student.objects.all()
    stu_data = {
        'students':students
    }
    return render(request,'students.html',context=stu_data)
注:
见名知意即可

在 urls.py 中添加
from django.conf.urls import url

from app6 import views

urlpatterns = [
    url(r'hello',views.hello),
    url(r'index',views.index),
    url(r'getstudents',views.getstudents)
]

创建 templates 文件夹,添加 students.html 对数据进行遍历
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3>
    {% for stu in students %}
    <li> {{ stu.s_name }}</li>
    {% endfor %}
</h3>
</body>
</html

进阶内容 使用 变量

def getstudents(request):

    students = Student.objects.all()
    stu_dict = {
    #     自己定义的字典
        'hobby':'play',
        'time':'5 years'
    }

    stu_data = {
        'students':students,
        'stu_dict':stu_dict
    #     stu_dict 是自己定义的字典
    }


    return render(request,'students.html',context=stu_data)






students_list.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul>
    {% for stu in students %}
    <li> {{ stu.s_name }}</li>
    {% endfor %}
    <hr/><br/><br/>


    <li> {{ students.0.s_name }}</li>
{#      0   输出第一个数据 #}

    <hr/><br/><br/>

    {% for stu in students %}
    <li> {{ stu.get_name }}</li>
{#    此处使用的是类中定义的方法#}
    {% endfor %}

    <h3>{{ stu_dict.hobby }}</h3>
{#stu_dict 是自己创建的字典类型,使用的 hobby 是自己添加的键值#}
</ul>
</body>
</html>

注:
stu.s_name  遍历的对象获取名字
students.0.s_name 获取第一条数据的名字
stu.get_name 使用类内的方法获取姓名

    def get_name(self):
        # 使用类内定义的函数获取名字
        return self.s_name

stu_dict.hobby 使用自定义的字典元素
注: 需要写到 context 内部的 键中
    stu_dict = {
    #     自己定义的字典
        'hobby':'play',
        'time':'5 years'
    }

    stu_data = {
        'students':students,
        'stu_dict':stu_dict
    #     stu_dict 是自己定义的字典
    }

Django学习路22_empty为空,forloop.counter 从1计数,.counter0 从0计数 .revcounter最后末尾数字是1,.revcounter0 倒序,末尾为 0
当查找的数据不存在,返回为 空时
在 html 中使用 {%empty%} 语句  进行显示
def getstudents(request):

    students = Student.objects.all().filter(s_name = 'qwer')
    # 指定一个不存在的值,
    # students = Student.objects.all()
    stu_dict = {
    #     自己定义的字典
        'hobby':'play',
        'time':'5 years'
    }

    stu_data = {
        'students':students,
        'stu_dict':stu_dict
    #     stu_dict 是自己定义的字典
    }

    return render(request,'students.html',context=stu_data)

html 中语句

    {% for stu in students %}
    <li> {{ stu.s_name }}</li>
        {% empty %}
        <h3>不存在该学生</h3>
    {% endfor %}
    <hr/><br/><br/>注: 如果为 空,则输出 <h3> 不存在该学生</h3> 这条语句

def getstudents(request):

    students = Student.objects.all()
    # 指定一个不存在的值,
    # students = Student.objects.all()
    stu_dict = {
    #     自己定义的字典
        'hobby':'play',
        'time':'5 years'
    }

    stu_data = {
        'students':students,
        'stu_dict':stu_dict
    #     stu_dict 是自己定义的字典
    }

    return render(request,'students.html',context=stu_data)

forloop.counter 示例

    {% for stu in students %}
    <li> {{ forloop.counter }} : {{ stu.s_name }}</li>
    {% endfor %}

forloop.counter0 示例

    {% for stu in students %}
    <li> {{ forloop.counter0 }} : {{ stu.s_name }}</li>
    {% endfor %}

forloop.revcounter 示例


    {% for stu in students %}
    <li> {{ forloop.revcounter }} : {{ stu.s_name }}</li>
    {% endfor %}

forloop.revcounter0 示例


    {% for stu in students %}
    <li> {{ forloop.revcounter0 }} : {{ stu.s_name }}</li>
    {% endfor %}

Django学习路23_if else 语句,if elif else 语句 forloop.first第一个元素 .last最后一个元素,注释
if else 格式

{%  if  条件 %}
<标签>语句</标签>
{%else%}
<标签>语句</标签>
{%endif}
标签都可以添加样式
{% for stu in students %}
    {% if forloop.first %}
        <li style="color: chartreuse">{{ stu.s_name }}</li>
        {% else %}
        <li>{{ stu.s_name }}</li>
    {% endfor %}

forloop.first 表示是否是第一个
color: chartreuse 浅绿色
for 循环和 if 判断 最后都要加上 endfor 和 endif
if elif else 格式

{%  if  条件 %}
<标签>语句</标签>
{%elif 条件 %}
<标签>语句</标签>
{%else %}
<标签>语句</标签>
{%endif}

{% for stu in students %}
    {% if forloop.first %}
        <li style="color: chartreuse">{{ stu.s_name }}</li>
        {% elif forloop.last %}
        <li style="color: blue">{{ stu.s_name }}</li>
        {% else %}
        <li>{{ stu.s_name }}</li>
        {% endif %}
    {% endfor %}

{#注释内容:  #}

{%comment%}

注释内容:

{%endcomment%}

Django学习路24_乘法和除法

urls 中
url(r'getnum',views.getnum)
views.py 中添加对应的函数

def getnum(request):
    num = 5
    context_num = {
        'num':num
    }
    return render(request,'num_ys.html',context=context_num)

html 中代码

<body>
{# 乘法 #}
<h2> {{num}} 当前的值</h2>
<h3>进行运算后的值 : {% widthratio num 1 5  %}</h3>

{# 除法 #}
<h2> {{num}} 当前的值</h2>
<h3>进行运算后的值 : {% widthratio num 5 1 %}</h3>

</body>

{%widthratio 数 分母 分子 %}

Django学习路25_ifequal 和 ifnotequal 判断数值是否相等及加减法 {{数值|add 数值}}
{% ifequal 数值 数值 %}

<body>
{# 判断是否相等 #}
num 当前的值 {{ num }}<br/>
{% ifequal num 5 %}
{# 判断 num 是否等于 5#}
    num 的值是 5
{% endifequal %}

</body>

{% ifnotequal 数值 数值 %}
{% ifnotequal%}


num 当前的值 {{ num }}<br/>
{% ifnotequal num 6 %}
{# 判断 num 是否等于 5#}
    num 的值不是 6
{% endifnotequal %}

{{ 数值 | add: 数值}}

{# 加法 #}
num 当前的值 {{ num }}<br/>
num + 5 的值是 :{{ num | add:5 }}

{{数值 | add:-数值}}

{# 减法 #}
num 当前的值 {{ num }}<br/>
num - 2 的值是 :{{ num | add:-2 }}
Django学习路26_转换字符串大小写 upper,lower
在 urls 中注册
url(r'getstr',views.getstr)

在 views.py 中添加函数

def getstr(request):    string = 'abc'    string_2 = 'ABC'    context_str = {        'string':string,        'string_2':'ABC'    }    return render(request,'strs.html',context=context_str)
{{ 字符串 | upper}}

<body>
当前的字符串为 {{ string }}<br/>
字符串大写后为 {{ string | upper }}
</body>

{{字符串|lower}}

<body>
当前的字符串为 {{ string_2 }}<br/>
字符串小写后为 {{ string_2 | lower }}
</body>

Django学习路27_HTML转义

谨慎使用
自动渲染语法
{{code|safe}}

urls.py 中添加对应的函数

url(r'getcode',views.getcode)
在 views.py 中添加

def getcode(request):
    code = "<h2> HTML 转义示例 </h2>"
    context_code = {
        'code':code
    }
    return render(request,'getcode.html',context=context_code)
getcode.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Getcode 示例</title>
</head>
<body>
<p>
    {{ code|safe }}
</p>
</body>
</html>
网站注入 js ,除非数据绝对安全,否则不要使用 
{{code|safe}}

在 根目录下,创建静态文件夹, static

建立 JavaScript 文件
添加内容
alert("网站被攻陷~"); 
在 views.py 中添加

def getcode(request):
    code = """
    <h2> HTML 转义示例 </h2>
    
    <script type="text/javascript">
        alert("网站被攻陷了~");
    </script>
    """

    context_code = {
        'code':code
    }
    return render(request,'getcode.html',context=context_code)

在 html 数据中添加

{{code|safe}} 

code 为传递过来的参数

里面有外界注入的 js 代码
进行自动渲染
autoescape off
不进行自动渲染
autoescape on


<body>
    {% autoescape on %}
        {{ code }}
    {% endautoescape %}
</body>

Django学习路28_ .html 文件继承及<block 标签>,include 'xxx.html'
在 templates 文件夹下创建 基类 base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
</head>
<body>
{% block header %}

{% endblock %}

{% block banner %}

{% endblock %}

{% block content %}

{% endblock %}

{% block footer %}

{% endblock %}
</body>
</html>

继承 base.html ,子类名为 home.html 

{% extends 'base.html' %}
{#继承 base.html #}

{% block header %}
<h2> header 模块 第一次继承 .html 文件</h2>
{% endblock %}

此时,继承的子类就可以显示

在 urls.py 中添加 
url(r'temp',views.temp),

在 views.py 中添加对应的函数

def temp(request):

    return render(request,'home.html',context={'title':'home'})

使用子类footer 继承 刚刚继承的 home.html

base   -> home  -> footer

footer.html 
{% extends '名称.html'%}
{% block 名称%}
语句
{%endblock%}


{% extends 'home.html' %}

{% block footer %}

    <h3> 继承了 子类 home 的 类,显示块为 footer </h3>
{% endblock %}

在 urls.py 中进行注册

url(r'footer',views.footer)

在 views.py 中添加 footer 函数

def footer(request):

    return render(request,'footer.html',context={'title':'footer'})

子类继承时,父类中显示的东西也会显示出来
子类可以继承父类的 block 块
使用 extends
语法:{% extends '名称.html'%}

当继承同一个 block 下的标签时,可能会出现覆盖
需要使用 {{block.super}}

footer.html 内容

{% extends 'home.html' %}

{% block footer %}

    <h3> 继承了 子类 home 的 类,显示块为 footer </h3>
{% endblock %}


{% block header %}

    继承了 子类 home 的 类,显示块为 header
{% endblock %}

注:
在 继承的 home.html 中也存在 block header 标签,如果没有使用 super 方法,会出现覆盖,使用子类的方法

使用 super 后,显示父类中的 block header

{% extends 'home.html' %}

{% block footer %}

    <h3> 继承了 子类 home 的 类,显示块为 footer </h3>
{% endblock %}


{% block header %}
    {{ block.super }}
    继承了 子类 home 的 类,显示块为 header
{% endblock %}

{% include '名称.html'%}
速度慢.

{% block footer %}
{% include 'footer.html' %}

{% endblock %}

注:
使用 footer.html 的内容

 


Django学习路29_css样式渲染 h3 标签
在 static 静态文件夹下创建 css 文件夹 home.css 
此时 home.css 路径是 'static/css/home.css'

在 对应的 home.html 文件中添加 css 样式

{% block ext_css %}
{#    <link rel="stylesheet" href="/static/css/home.css">#}
{#    导入样式#}
    <link rel="stylesheet" href="{% static 'css/home.css' %}"
{#       使用相对路径#}
{% endblock %}

注:
导入方式:
 <link rel="stylesheet" href="/static/css/home.css">
使用绝对路径,如果路径修改,则很容易出错

<link rel="stylesheet" href="{% static 'css/home.css' %}"
使用相对路径,在使用之前,要先在项目的 settings 中添加

STATIC_URL = '/static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'static'),
]
通知项目,存在该目录
home.html 内容

{% extends 'base.html' %}
{#继承 base.html #}
{% load static %}
{% block header %}
<h2> header 模块 第一次继承 .html 文件</h2>
{% endblock %}

{% block footer %}
{% include 'footer.html' %}

{% endblock %}

{% block ext_css %}
{#    <link rel="stylesheet" href="/static/css/home.css">#}
{#    导入样式#}
    <link rel="stylesheet" href="{% static 'css/home.css' %}"
{#       使用相对路径#}
{% endblock %}
home.css 内容
标签名{
  属性:值;    
}

h3{
    color:green;
}
本次使用的是 footer.html  继承了 home.html 的子类

footer.html 内容

{% extends 'home.html' %}

{% block footer %}

    <h3> 继承了 子类 home 的 类,显示块为 footer </h3>
{% endblock %}


{% block header %}
    {{ block.super }}
    继承了 子类 home 的 类,显示块为 header
{% endblock %}


{% block content %}
    <h3>做一件事,就把这件事做好</h3>

{% endblock %}
在 urls 中注册

 url(r'footer',views.footer)

在 views 中实现

def footer(request):

    return render(request,'footer.html',context={'title':'footer'})
注:
在 settings 中的 
DEBUG = True

当 DEBUG 为 False 时,会发生界面找不到

核心语句写法:

导入:
<link rel = "stylesheet" href = "{%static '相对路径'%}">

 <link rel="stylesheet" href="{% static 'css/home.css' %}"


继承:
{% extends '文件名.html'%}

{% extends 'base.html' %}
{% extends 'home.html' %}

css 样式:
标签名{
  属性:值;
}

h3{
    color:green;
}

千万要进行注册

STATIC_URL = '/static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'static'),
]

Django学习路30_view中存在重复名时,取第一个满足条件的
在 settings 中添加 

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app.apps.AppConfig'
]

在 urls 中添加 对应的函数

from django.conf.urls import url

from app import views

urlpatterns = [
    url(r'getok',views.getok),
    url(r'getokok',views.getokok)
]

注:
使用 url  不使用 path
from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.
def getok(request):
    return HttpResponse("您得到的回复是 OK ")

def getokok(request):
    return HttpResponse("您得到的回复是 OKOK  ")

Django学习路31_使用 locals 简化 context 写法,点击班级显示该班学生信息
urls 中 进行注册

url(r'grades',views.grades)

views 中编写函数

def grades(request):
    grades_list = Grade.objects.all()
    # 使用 locals 获取本地变量
    return render(request,'grades_list.html',context = locals())
html 中编写页面显示

<body>
<h2>班级列表</h2>
<ul>
    {% for grade in grades_list %}
    <li> {{ grade.g_name }}</li>
    {% endfor %}
</ul>
</body>

render 参数写为 context = locals()

点击班级名,跳转查看所有学生信息

在 html 循环中使用 

<a href = "函数名/{{grade.g_id}}">班级名称</a>


在 urls 中声明 "显示名称/(d+)/" 
(d+)  返回到函数中一个参数,通过参数可以获取到学生的信息

类名.objects.filter 内参数 s_grade_id = g_id
Django学习路32_创建管理员及内容补充+前面内容复习
创建管理员

python manage.py createsuperuser

 

 

数据库属性命名限制

1.不能是python的保留关键字
2.不允许使用连续的下划线,这是由django的查询方式决定的
3.定义属性时需要指定字段类型,通过字段类型的参数指定选项
语法如下:
属性名=models.字段类型(选项)
字段类型
使用时需要引入django.db.models包,字段类型如下:
AutoField:自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性

BooleanField:布尔字段,值为True或False

NullBooleanField:支持Null、True、False三种值

CharField(max_length=字符长度):字符串
参数max_length表示最大字符个数

TextField:大文本字段,一般超过4000个字符时使用

IntegerField:整数

DecimalField(max_digits=None, decimal_places=None):十进制浮点数

参数max_digits表示总位数

参数decimal_places表示小数位数

FloatField:浮点数

DateField:[auto_now=False, auto_now_add=False]):日期
参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false。
参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false

参数auto_now_add和auto_now是相互排斥的,组合将会发生错误

TimeField:时间,参数同DateField

DateTimeField:日期时间,参数同DateField

FileField:上传文件字段

ImageField:继承于FileField,对上传的内容进行校验,确保是有效的图片

选项:

null:如果为True,表示允许为空,默认值是False

blank:如果为True,则该字段允许为空白,默认值是False

对比:null是数据库范畴的概念,blank是表单验证证范畴的

db_column:字段的名称,如果未指定,则使用属性的名称

db_index:若值为True, 则在表中会为此字段创建索引,默认值是False

default:默认值

primary_key:若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用

unique:如果为True, 这个字段在表中必须有唯一值,默认值是False。

get() 获取数据的坑
注:之前写过


get():返回表中满足条件的一条且只能有一条数据

如果查到多条数据,则抛异常:MultipleObjectsReturned

查询不到数据,则抛异常:DoesNotExist

判断条件中的 属性列__参数 的补充

1.判等 exact

例:查询编号为1的图书
BookInfo.objects.get(id=1)
BookInfo.objects.get(id__exact=1)


2.模糊查询 contains

例:查询书名包含''的图书。contains

BookInfo.objects.filter(btitle__contains='')
例:查询书名以''结尾的图书 endswith 开头:startswith
BookInfo.objects.filter(btitle__endswith='')

3.空查询 isnull 

select * from booktest_bookinfo where title is not null;

例:查询书名不为空的图书。isnull 
BookInfo.objects.filter(btitle__isnull=False)

4.范围查询 in 

select * from booktest_bookinfo where id in (1,3,5)
例:查询编号为1或3或5的图书。
BookInfo.objects.filter(id__in = [1,3,5])

5.比较查询 
gt 大于
lt 小于 
gte 大于等于
lte 小于等于

例:查询编号大于3的图书。
BookInfo.objects.filter(id__gt = 3)

6.日期查询 year

例:查询1980年发表的图书。
BookInfo.objects.filter(bpub_date__year=1980)

例:查询1980年1月1日后发表的图书。
from datetime import date
BookInfo.objects.filter(bpub_date__gt = date(1980,1,1))

7.返回不满足条件的数据 exclude

例:查询id不为3的图书信息。
BookInfo.objects.exclude(id=3)
F对象
作用:用于类属性之间的比较条件

使用之前需要先导入:
from django.db.models import F

例:查询图书阅读量大于评论量图书信息。
BookInfo.objects.filter(bread__gt = F('bcomment'))

例:查询图书阅读量大于2倍评论量图书信息。
BookInfo.objects.filter(bread__gt = F('bcomment')*2)



Q对象
作用:用于查询时的逻辑条件
not and or,可以对Q对象进行&|~操作

使用之前需要先导入:
from django.db.models import Q

例:查询id大于3且阅读量大于30的图书的信息。
BookInfo.objects.filter(id__gt=3, bread__gt=30)

BookInfo.objects.filter(Q(id__gt=3)&Q(bread__gt=30))

例:查询id大于3或者阅读量大于30的图书的信息。
BookInfo.objects.filter(Q(id__gt=3)|Q(bread__gt=30))

例:查询id不等于3图书的信息。
BookInfo.objects.filter(~Q(id=3))

order_by 
QuerySet对象.order_by('属性')

作用:进行查询结果进行排序


例:查询所有图书的信息,按照id从小到大进行排序
BookInfo.objects.all().order_by('id')
BookInfo.objects.order_by('id')

例:查询所有图书的信息,按照id从大到小进行排序。
BookInfo.objects.all().order_by('-id')

例:把id大于3的图书信息按阅读量从大到小排序显示;
BookInfo.objects.filter(id__gt=3).order_by('-bread')

注:
属性上写上 - 号,表示从大到小进行排序

聚合函数
Sum Count Max Min Avg

aggregate(聚合函数('属性'))
返回一个字典对象

使用前需先导入聚合类: 
from django.db.models import Sum,Count,Max,Min,Avg

例:查询所有图书的数目 Count
BookInfo.objects.aggregate(Count('id'))
返回值类型:
{'id__count': 5}

例:查询所有图书阅读量的总和。
BookInfo.objects.aggregate(Sum('bread'))
{'bread__sum': 126}

count函数 返回值是一个数字
作用:统计满足条件数据的数目

例:统计所有图书的数目。
BookInfo.objects.count()
例:统计id大于3的所有图书的数目
BookInfo.objects.filter(id__gt=3).count()


查询相关函数返回值总结:
get:返回一个对象 
all:QuerySet 返回所有数据
filter:QuerySet 返回满足条件的数据
exclude:QuerySet 返回不满条件的数据
order_by:QuerySet 对查询结果进行排序
aggregate:字典 进行聚合操作
count:数字 返回查询集中数据的数目
get,filter,exclude参数中可以写查询条件。

查询集特性:
1.惰性查询:
只有在实际使用查询集中的数据的时候才会发生对数据库的真正查询

2.缓存:
当使用的是同一个查询集时,第一次的时候会发生实际数据库的查询,然后把结果缓存起来,之后再使用这个查询集时,使用的是缓存中的结果

限制查询集:
可以对一个查询集进行取下标或者切片操作来限制查询集的结果
b[0]就是取出查询集的第一条数据
b[0:1].get()也可取出查询集的第一条数据

如果b[0]不存在,会抛出IndexError异常

如果b[0:1].get()不存在,会抛出DoesNotExist异常。多条时抛MultiObjectsReturned
对一个查询集进行切片操作会产生一个新的查询集,下标不允许为负数

exists:判断一个查询集中是否有数据  True False

模型类关系
1.一对多关系
例:图书类-英雄类 
models.ForeignKey() 定义在多的类中

2.多对多关系
例:新闻类-新闻类型类 体育新闻 国际
models.ManyToManyField() 定义在哪个类中都可以

3.一对一关系
例:员工基本信息类-员工详细信息类. 员工工号
models.OneToOneField定义在哪个类中都可以

关联查询(一对多)
在一对多关系中,一对应的类我们把它叫做一类,多对应的那个类我们把它叫做多类,我们把多类中定义的建立关联的类属性叫做关联属性

例:查询图书id为1的所有英雄的信息。
    book = BookInfo.objects.get(id=1)
    book.heroinfo_set.all()

通过模型类查询:
    HeroInfo.objects.filter(hbook_id=1)
例:查询id为1的英雄所属图书信息。
    hero =HeroInfo.objects.get(id=1)
    hero.hbook

通过模型类查询:
BookInfo.objects.filter(heroinfo__id=1)

由一类的对象查询多类的时候:
    一类的对象.多类名小写_set.all() #查询所用数据
由多类的对象查询一类的时候:
    多类的对象.关联属性  #查询多类的对象对应的一类的对象
由多类的对象查询一类对象的id时候:
    多类的对象. 关联属性_id

通过模型类实现关联查询:

例:查询图书信息,要求图书中英雄的描述包含''
BookInfo.objects.filter(heroinfo__hcomment__contains='')

例:查询图书信息,要求图书中的英雄的id大于3
BookInfo.objects.filter(heroinfo__id__gt=3)

例:查询书名为“天龙八部”的所有英雄
HeroInfo.objects.filter(hbook__btitle='天龙八部')

通过多类的条件查询一类的数据:
    一类名.objects.filter(多类名小写__多类属性名__条件名) 

通过一类的条件查询多类的数据:
    多类名.objects.filter(关联属性__一类属性名__条件名)
插入、更新和删除

调用模型类对象的save方法实现对模型类对应数据表的插入和更新
调用模型类对象的delete方法实现对模型类对应数据表数据的删除

自关联是一种特殊的一对多关系
管理器
objects
BookInfo.objects.all()
答:objects是Django帮我自动生成的管理器对象
    通过这个管理器可以实现对数据的查询
objects是models.Manger类的一个对象
自定义管理器后 Django不再帮我们生成默认的objects管理器

1.自定义一个管理器类,这个类继承models.Manger类
2.再在具体的模型类里定义一个自定义管理器类的对象

自定义管理器类的应用场景:
1.改变查询的结果集
比如调用BookInfo.books.all()返回的是没有删除的图书的数据
2.添加额外的方法
管理器类中定义一个方法帮我们创建对应的模型类对象
使用self.model()就可以创建一个跟自定义管理器对应的模型类对象

元选项

Django默认生成的表名:
    应用名小写_模型类名小写。
元选项:
需要在模型类中定义一个元类Meta
在里面定义一个类属性db_table就可以指定表名

Django学习路33_url 地址及删除元素 delete() 和重定向 return redirect('路径')
保存日期

def create(request):
    '''新增一本图书'''
    # 1.创建BookInfo对象
    b = BookInfo()
    b.btitle = '流星蝴蝶剑'
    b.bpub_date = date(1990,1,1)
    # 2.保存进数据库
    b.save()
    # 3.返回应答,让浏览器再访问/index,重定向
    return HttpResponse('ok')
    # return HttpResponseRedirect('/index')
    # return redirect('/index')

使用 结果集对象.delete()  进行删除

from django.shortcuts import render,redirect # 导入重定向函数
redirect('路径') 实现重定向


def delete(request, bid):
    '''删除点击的图书'''
    # 1.通过bid获取图书对象
    book = BookInfo.objects.get(id=bid)
    # 2.删除
    book.delete()
    # 3.重定向,让浏览器访问/index
    # return HttpResponseRedirect('/index')
    return redirect('/index')

Django学习路34_models 文件创建数据表
from django.db import models

# Create your models here.
class BookInfoManager(models.Manager):
    '''图书模型管理器类'''
    # 1.改变原有查询的结果集
    def all(self):
        # 1.调用父类的all方法,获取所有数据
        books = super().all() # QuerySet
        # 2.对books中的数据进行过滤
        books = books.filter(isDelete=False)
        # 返回books
        return books

    # 2.封装方法,操作模型类对应的数据表(增删改查)
    def create_book(self, btitle, bpub_date):
        '''添加一本图书'''
        # 1.创建一个图书对象
        # 获取self所在的模型类
        model_class = self.model
        book = model_class()
        # book = BookInfo()
        book.btitle = btitle
        book.bpub_date = bpub_date
        # 2.添加进数据库
        book.save()
        # 3.返回book
        return book


# 一类
# booktest2_bookinfo
class BookInfo(models.Model):
    '''图书模型类'''
    # 图书名称
    btitle = models.CharField(max_length=20, db_column='title')
    # 图书名字唯一
    # btitle = models.CharField(max_length=20, unique=True, db_index=True)
    # 价格,最大位数为10,小数为2
    # bprice = models.DecimalField(max_digits=10, decimal_places=2)
    # 出版日期
    bpub_date = models.DateField()
    # bpub_date = models.DateField(auto_now_add=True) # 创建时间
    # bpub_date = models.DateField(auto_now=True) # 更新时间
    # 阅读量
    bread = models.IntegerField(default=0)
    # 评论量
    bcomment = models.IntegerField(default=0)
    # 删除标记
    isDelete = models.BooleanField(default=False)

    # book = models.Manager() # 自定一个Manager类对象,管理器对象
    objects = BookInfoManager() # 自定义一个BookInfoManager类的对象

    # @classmethod
    # def create_book(cls, btitle, bpub_date):
    #     '''添加一本图书'''
    #     # 创建一个cls类的对象
    #     obj = cls()
    #     obj.btitle = btitle
    #     obj.bpub_date = bpub_date
    #     # 添加进数据库
    #     obj.save()
    #     # 返回obj
    #     return obj

    class Meta:
        db_table = 'bookinfo' # 指定模型类对应表名



# 多类
class HeroInfo(models.Model):
    '''英雄人物模型类'''
    # 英雄名
    hname = models.CharField(max_length=20)
    # 性别
    hgender = models.BooleanField(default=False)
    # 备注
    hcomment = models.CharField(max_length=200, null=True, blank=False)
    # 关系属性
    hbook = models.ForeignKey('BookInfo',on_delete=True)
    # 删除标记
    isDelete = models.BooleanField(default=False)
'''
# 新闻类型类
class NewsType(models.Model):
    # 类型名
    type_name = models.CharField(max_length=20)
    # 关系属性,代表类型下面的信息
    type_news = models.ManyToManyField('NewsInfo')

# 新闻类
class NewsInfo(models.Model):
    # 新闻标题
    title = models.CharField(max_length=128)
    # 发布时间
    pub_date = models.DateTimeField(auto_now_add=True)
    # 信息内容
    content = models.TextField()
    # 关系属性, 代表信息所属的类型
    # news_type = models.ManyToManyField('NewsType')

# 员工基本信息类
class EmployeeBasicInfo(models.Model):
    # 姓名
    name = models.CharField(max_length=20)
    # 性别
    gender = models.BooleanField(default=False)
    # 年龄
    age = models.IntegerField()
    # 关系属性,代表员工的详细信息
    employee_detail = models.OneToOneField('EmployeeDetailInfo')

# 员工详细信息类
class EmployeeDetailInfo(models.Model):
    # 联系地址
    addr = models.CharField(max_length=256)
    # 教育经历
    # 关系属性,代表员工基本信息
    # employee_basic = models.OneToOneField('EmployeeBasicInfo')
'''

class AreaInfo(models.Model):
    '''地区模型类'''
    # 地区名称
    atitle = models.CharField(max_length=20)
    # 关系属性,代表当前地区的父级地区
    aParent = models.ForeignKey('self', null=True, blank=True,on_delete=True)

    # class Meta:
    #     db_table = 'areas'

Django学习路35_视图使用方法(复制的代码) + 简单总结
from django.shortcuts import render,redirect
from django.http import HttpResponse,JsonResponse
from datetime import datetime,timedelta
# Create your views here.


# request就是HttpRequest类型的对象
# request包含浏览器请求的信息
def index(request):
    '''首页'''
    # num = 'a' + 1
    # print(request.path)
    response = render(request, 'booktest/index.html')
    response.write('hello')
    return response


def show_arg(request, num):
    return HttpResponse(num)


def login(request):
    '''显示登录页面'''
    # 判断用户是否登录
    if request.session.has_key('islogin'):
        # 用户已登录, 跳转到首页
        return redirect('/index')
    else:
        # 用户未登录
        # 获取cookie username
        if 'username' in request.COOKIES:
            # 获取记住的用户名
            username = request.COOKIES['username']
        else:
            username = ''

        return render(request, 'booktest/login.html', {'username':username})


def login_check(request):
    '''登录校验视图'''
    # request.POST 保存的是post方式提交的参数 QueryDict
    # request.GET 保存是get方式提交的参数
    print(request.method)
    # 1.获取提交的用户名和密码
    username = request.POST.get('username')
    password = request.POST.get('password')
    remember = request.POST.get('remember')
    # 2.进行登录的校验
    # 实际开发:根据用户名和密码查找数据库
    # 模拟: smart 123
    if username == 'smart' and password == '123':
        # 用户名密码正确,跳转到首页
        response = redirect('/index')

        # 判断是否需要记住用户名
        if remember == 'on':
            # 设置cookie username,过期时间1周
            response.set_cookie('username', username, max_age=7*24*3600)

        # 记住用户登录状态
        # 只有session中有islogin,就认为用户已登录
        request.session['islogin'] = True

        # 返回应答
        return response
    else:
        # 用户名或密码错误,跳转到登录页面
        return redirect('/login')


# /test_ajax
def ajax_test(request):
    '''显示ajax页面'''
    return render(request, 'booktest/test_ajax.html')


def ajax_handle(request):
    '''ajax请求处理'''
    # 返回的json数据 {'res':1}
    return JsonResponse({'res':1})


# /login_ajax
def login_ajax(request):
    '''显示ajax登录页面'''
    return render(request, 'booktest/login_ajax.html')


# /login_ajax_check
def login_ajax_check(request):
    '''ajax登录校验'''
    # 1.获取用户名和密码
    username = request.POST.get('username')
    password = request.POST.get('password')

    # 2.进行校验,返回json数据
    if username == 'smart' and password == '123':
        # 用户名密码正确
        return JsonResponse({'res':1})
        # return redirect('/index') ajax请求在后台,不要返回页面或者重定向
    else:
        # 用户名或密码错误
        return JsonResponse({'res':0})


# /set_cookie
def set_cookie(request):
    '''设置cookie信息'''
    response = HttpResponse('设置cookie')
    # 设置一个cookie信息,名字为num, 值为1
    response.set_cookie('num', 1, max_age=14*24*3600)
    # response.set_cookie('num2', 2)
    # response.set_cookie('num', 1, expires=datetime.now()+timedelta(days=14))
    # 返回response
    return response


# /get_cookie
def get_cookie(request):
    '''获取cookie的信息'''
    # 取出cookie num的值
    num = request.COOKIES['num']
    return HttpResponse(num)


# /set_session
def set_session(request):
    '''设置session'''
    request.session['username'] = 'smart'
    request.session['age'] = 18
    # request.session.set_expiry(5)
    return HttpResponse('设置session')


# /get_session
def get_session(request):
    '''获取session'''
    username = request.session['username']
    age = request.session['age']
    return HttpResponse(username+':'+str(age))


# /clear_session
def clear_session(request):
    '''清除session信息'''
    # request.session.clear()
    request.session.flush()
    return HttpResponse('清除成功')
urls.py 内容

from django.conf.urls import url
from booktest import views

urlpatterns = [
    url(r'^index$', views.index), # 首页
    # url(r'^showarg(d+)$', views.show_arg), # 捕获url参数:位置参数
    url(r'^showarg(?P<num>d+)$', views.show_arg),# 捕获url参数:关键字参数

    url(r'^login$', views.login), # 显示登录页面
    url(r'^login_check$', views.login_check), # 用户登录校验

    url(r'^test_ajax$', views.ajax_test), # 显示ajax页面
    url(r'^ajax_handle$', views.ajax_handle), # ajax处理

    url(r'^login_ajax$', views.login_ajax), # 显示ajax登录页面
    url(r'^login_ajax_check$', views.login_ajax_check), # ajax登录校验

    url(r'^set_cookie$', views.set_cookie), # 设置cookie
    url(r'^get_cookie$', views.get_cookie), # 获取cookie

    url(r'^set_session$', views.set_session), # 设置session
    url(r'^get_session$', views.get_session), # 获取session
    url(r'^clear_session$', views.clear_session), # 清除session
]

展示参数

def show_arg(request, num):
    return HttpResponse(num)


判断用户是否登录

request.session.has_key('islogin')

重定向

return redirect('/index')

获取cookie

request.COOKIES


获取用户提交的用户名和密码

username = request.POST.get('username')
password = request.POST.get('password')

判断是否需要记住

remember = request.POST.get('remember')
        if remember == 'on':
            # 设置cookie username,过期时间1周
            response.set_cookie('username', username, max_age=7*24*3600)


只要 session中有islogin,就认为用户已登录

request.session['islogin'] = True

返回 JSON 数据

def ajax_handle(request):
    '''ajax请求处理'''
    # 返回的json数据 {'res':1}
    return JsonResponse({'res':1})

判断是否登录

def login_ajax_check(request):
    '''ajax登录校验'''
    # 1.获取用户名和密码
    username = request.POST.get('username')
    password = request.POST.get('password')

    # 2.进行校验,返回json数据
    if username == 'smart' and password == '123':
        # 用户名密码正确
        return JsonResponse({'res':1})
        # return redirect('/index') ajax请求在后台,不要返回页面或者重定向
    else:
        # 用户名或密码错误
        return JsonResponse({'res':0})


设置 cookie 信息

response.set_cookie('num', 1, max_age=14*24*3600)

获取 cookie 信息

num = request.COOKIES['num']

设置 session 信息
request.session['username'] = 'smart'


def set_session(request):
    '''设置session'''
    request.session['username'] = 'smart'
    request.session['age'] = 18
    # request.session.set_expiry(5)
    return HttpResponse('设置session')

获取 session 

age = request.session['age']

清除 session 信息

request.session.flush()

def clear_session(request):
    '''清除session信息'''
    # request.session.clear()
    request.session.flush()
    return HttpResponse('清除成功')

Django学习路36_函数参数 反向解析 修改404 页面

 

在 templates 中创建对应文件名的 html 文件 (404.html)
注:
开发者服务器发生变更是因为 python 代码发生变化
如果 html 文件发生变化,服务器不会进行重启
需要自己手动修改
注意就近原则,如果有重复名字,先用最近的
Django学习路37_request属性

 

打印元信息,基本上都会打印出来
类字典结构的 key 键 允许重复

 

get 请求可以传参,但是长度有限制 最大不能超过 2K 
post 文件上传使用

get 参数 默认放在网址中
post 在请求体中

post 请求可以获取 get 请求参数
类字典结构:
<QueryDict>
键可以重复


字典结构:
键是 哈希表,保证不重复

 


打印 访问网站的用户的 IP 地址

老男孩Django笔记(非原创)
3、WEB框架

    MVC
        Model       View       Controller
        数据库   模板文件    业务处理
    
    
    MTV

        Model    Template     View
        数据库   模板文件    业务处理
    
    
    ############## WEB:MVC、MTV
    
4、Django
    
    pip3 install django
    
    
    C:Python35Scripts
    
    # 创建Django工程
    django-admin startproject 【工程名称】
    
        mysite
            - mysite        # 对整个程序进行配置
                - init
                - settings  # 配置文件
                - url       # URL对应关系
                - wsgi      # 遵循WSIG规范,uwsgi + nginx
            - manage.py     # 管理Django程序:
                                - python manage.py 
                                - python manage.py startapp xx
                                - python manage.py makemigrations
                                - python manage.py migrate
        
        
        
    # 运行Django功能
    python manage.py runserver 127.0.0.1:8001
    
    
    chouti
        - chouti
            - 配置
        - 主站 app
        - 后台管理 app
    
    
    
    # 创建app
    python manage.py startapp cmdb
    python manage.py startapp openstack
    python manage.py startapp xxoo....
    
    
    app:
        migrations     数据修改表结构
        admin          Django为我们提供的后台管理
        apps           配置当前app
        models         ORM,写指定的类  通过命令可以创建数据库结构
        tests          单元测试
        views          业务代码
    
    
    
    1、配置模板的路径
    
        TEMPLATES = [
                {
                    'BACKEND': 'django.template.backends.django.DjangoTemplates',
                    'DIRS': [os.path.join(BASE_DIR, 'templates')],
                    'APP_DIRS': True,
                    'OPTIONS': {
                        'context_processors': [
                            'django.template.context_processors.debug',
                            'django.template.context_processors.request',
                            'django.contrib.auth.context_processors.auth',
                            'django.contrib.messages.context_processors.messages',
                        ],
                    },
                },
            ]
    2、配置静态目录
        static
    
        STATICFILES_DIRS = (
            os.path.join(BASE_DIR, 'static'),
        )

        
        <link rel="stylesheet" href="/static/commons.css" />
    

内容整理
    1. 创建Django工程
            django-admin startproject 工程名

    2. 创建APP
        cd 工程名
        python manage.py startapp cmdb

    3、静态文件
        project.settings.py
        
        STATICFILES_DIRS = (
            os.path.join(BASE_DIR, "static"),
        )
    
    4、模板路径
    
        DIRS ==>    [os.path.join(BASE_DIR,'templates'),]
        
    5、settings中
        
        middlerware
        
            # 注释 csrf
            
            
    6、定义路由规则
        url.py
        
            "login" --> 函数名
            
    7、定义视图函数
        app下views.py
            
            def func(request):
                # request.method   GET / POST
                
                # http://127.0.0.1:8009/home?nid=123&name=alex
                # request.GET.get('',None)   # 获取请求发来的而数据
                
                # request.POST.get('',None)
                
                
                # return HttpResponse("字符串")
                # return render(request, "HTML模板的路径")
                # return redirect('/只能填URL')
                
    8、模板渲染
        特殊的模板语言
        
            -- {{ 变量名 }}
        
                def func(request):
                    return render(request, "index.html", {'current_user': "alex"})
        
                    
                index.html
                
                <html>
                ..
                    <body>
                        <div>{{current_user}}</div>
                    </body>
                
                </html>
                
                ====> 最后生成的字符串
                
                <html>
                ..
                    <body>
                        <div>alex</div>
                    </body>
                
                </html>
            -- For循环
                def func(request):
                    return render(request, "index.html", {'current_user': "alex", 'user_list': ['alex','eric']})
        
                    
                index.html
                
                <html>
                ..
                    <body>
                        <div>{{current_user}}</div>
                        
                        <ul>
                            {% for row in user_list %}
                            
                                {% if row == "alex" %}
                                    <li>{{ row }}</li>
                                {% endif %}
                                
                            {% endfor %}
                        </ul>
                        
                    </body>
                
                </html>
                
            #####索引################# 
                def func(request):
                    return render(request, "index.html", {
                                'current_user': "alex", 
                                'user_list': ['alex','eric'], 
                                'user_dict': {'k1': 'v1', 'k2': 'v2'}})
        
                    
                index.html
                
                <html>
                ..
                    <body>
                        <div>{{current_user}}</div>
                        
                        <a> {{ user_list.1 }} </a>
                        <a> {{ user_dict.k1 }} </a>
                        <a> {{ user_dict.k2 }} </a>
                        
                    </body>
                
                </html>
            
            ###### 条件
            
                def func(request):
                    return render(request, "index.html", {
                                'current_user': "alex", 
                                "age": 18,
                                'user_list': ['alex','eric'], 
                                'user_dict': {'k1': 'v1', 'k2': 'v2'}})
        
                    
                index.html
                
                <html>
                ..
                    <body>
                        <div>{{current_user}}</div>
                        
                        <a> {{ user_list.1 }} </a>
                        <a> {{ user_dict.k1 }} </a>
                        <a> {{ user_dict.k2 }} </a>
                        
                        {% if age %}
                            <a>有年龄</a>
                            {% if age > 16 %}
                                <a>老男人</a>
                            {% else %}
                                <a>小鲜肉</a>
                            {% endif %}
                        {% else %}
                            <a>无年龄</a>
                        {% endif %}
                    </body>
                
                </html>
    
    
    
XXOO管理:
    MySQL
    SQLAlchemy
    主机管理(8列):
        IP
        端口
        业务线
        ...
        
    用户表:
        用户名
        密码
    
    功能:
        1、 登录
        2、主机管理页面
            - 查看所有的主机信息(4列)
            - 增加主机信息(8列) ** 模态对话框
        3、查看详细
            url:
                "detail" -> detail
        
            def detail(reqeust):
                nid = request.GET.get("nid")
                v = select * from tb where id = nid
                ...
        4、删除
            del_host -> delete_host
            
            def delete_host(request):
                nid = request.POST.get('nid')
                delete from tb where id = nid
                return redirect('/home')
            
    

上节内容回顾:
    1、Django请求生命周期
        -> URL对应关系(匹配) -> 视图函数 -> 返回用户字符串
        -> URL对应关系(匹配) -> 视图函数 -> 打开一个HTML文件,读取内容
        
    2、创建django projcet

        django-admin startproject mysite
        

        ..
        
        mysite
            mysite
                - 配置文件
                - url.py
                - settings.py
            
        cd mysite
        python manage.py startapp cmdb
        
        mysite
            mysite
                - 配置文件
                - url.py
                - settings.py
            cmdb
                - views.py
                - admin.py
                - models.py # 创建数据库表

    3、配置
        
        模板路径
        静态文件路径
        # CSRF
        
    4、编写程序

        a. url.py
            
            /index/    ->   func
            
        b. views.py
            
            def func(request):
                # 包含所有的请求数据
                ...
                return HttpResponse('字符串')
                return render(request, 'index.html', {''})
                retrun redirect('URL')
                
        c. 模板语言
            return render(request, 'index.html', {'li': [11,22,33]})
            
            {% for item in li %}
                <h1>{{item}}</h1>
            {% endfor %}
            
            
            ***********  索引用点 **********
            <h2> {{item.0 }} </h2>

一、路由系统,URL
    1、url(r'^index/', views.index),    
       url(r'^home/', views.Home.as_view()),
    2、url(r'^detail-(d+).html', views.detail),  
    3、url(r'^detail-(?P<nid>d+)-(?P<uid>d+).html', views.detail)
       
       PS:
            def detail(request, *args,**kwargs):
                pass
    
       实战:
            a. 
                url(r'^detail-(d+)-(d+).html', views.detail),
                
                def func(request, nid, uid):
                    
                    pass
            
                def func(request, *args):
                    args = (2,9)
                    
                    
                def func(request, *args, **kwargs):
                    args = (2,9)
       
            b. 
                url(r'^detail-(?P<nid>d+)-(?P<uid>d+).html', views.detail)
                
                def func(request, nid, uid):
                    pass
                    
                def funct(request, **kwargs):
                    kwargs = {'nid': 1, 'uid': 3}
                    
                def func(request, *args, **kwargs):
                    args = (2,9)
    4、 name
        
        对URL路由关系进行命名, ***** 以后可以根据此名称生成自己想要的URL *****
        
        url(r'^asdfasdfasdf/', views.index, name='i1'),
        url(r'^yug/(d+)/(d+)/', views.index, name='i2'),
        url(r'^buy/(?P<pid>d+)/(?P<nid>d+)/', views.index, name='i3'),
        
        
        
        def func(request, *args, **kwargs):
            from django.urls import reverse
            
            url1 = reverse('i1')                              # asdfasdfasdf/
            url2 = reverse('i2', args=(1,2,))                 # yug/1/2/
            url3 = reverse('i3', kwargs={'pid': 1, "nid": 9}) # buy/1/9/
        
        
        xxx.html
            
            {% url "i1" %}               # asdfasdfasdf/
            {% url "i2" 1 2 %}           # yug/1/2/
            {% url "i3" pid=1 nid=9 %}   # buy/1/9/
        
        注:
            # 当前的URL
            request.path_info 
    5、多级路由
        
        project/urls.py
            from django.conf.urls import url,include
            from django.contrib import admin

            urlpatterns = [
                url(r'^cmdb/', include("app01.urls")),
                url(r'^monitor/', include("app02.urls")),
            ]
            
        app01/urls.py
            from django.conf.urls import url,include
            from django.contrib import admin
            from app01 import views

            urlpatterns = [
                url(r'^login/', views.login),
            ]
            
        app02/urls.py
            from django.conf.urls import url,include
            from django.contrib import admin
            from app02 import views

            urlpatterns = [
                url(r'^login/', views.login),
            ]
    
二、视图
    1、获取用户请求数据
        request.GET
        request.POST
        request.FILES
        PS:
            GET:获取数据                
            POST:提交数据
            
    2、checkbox等多选的内容
        request.POST.getlist()
    3、上传文件
        # 上传文件,form标签做特殊设置
        obj = request.FILES.get('fafafa')
        obj.name
        f = open(obj.name, mode='wb')
        for item in obj.chunks():
            f.write(item)
        f.close()
    
    4、FBV & CBV
       function base view
       
        url.py
            index -> 函数名
            
        view.py
            def 函数(request):
                ...
        ====/index/ -> 函数名
            
        /index/ ->====》
        
        建议:两者都用
        
    5、装饰器


四、ORM操作
    select * from tb where id > 1
    # 对应关系
    models.tb.objects.filter(id__gt=1)
    models.tb.objects.filter(id=1)
    models.tb.objects.filter(id__lt=1)
    
    创建类
    
    a. 先写类
        from django.db import models

        # app01_userinfo
        class UserInfo(models.Model):
            # id列,自增,主键
            # 用户名列,字符串类型,指定长度
            username = models.CharField(max_length=32)
            password = models.CharField(max_length=64)
        
    b. 注册APP

        INSTALLED_APPS = [
            'django.contrib.admin',
            'django.contrib.auth',
            'django.contrib.contenttypes',
            'django.contrib.sessions',
            'django.contrib.messages',
            'django.contrib.staticfiles',
            'app01',
        ]
    c. 执行命令
        python manage.py  makemigrations
        python manage.py  migrate
        
    d. ********** 注意 ***********
        Django默认使用MySQLdb模块链接MySQL
        主动修改为pymysql,在project同名文件夹下的__init__文件中添加如下代码即可:
            import pymysql
            pymysql.install_as_MySQLdb()
    
    1. 根据类自动创建数据库表
        # app下的models.py
    
        python manage.py  makemigrations
        python manage.py  migrate
        
        
        字段:
            字符串类型
            
            
            数字
            
            
            时间
            
            
            二进制
            
            自增(primary_key=True)
            
        字段的参数:
            null               -> db是否可以为空
            default            -> 默认值
            primary_key        -> 主键
            db_column          -> 列名
            db_index           -> 索引
            unique               -> 唯一索引
            unique_for_date    -> 
            unique_for_month
            unique_for_year
            auto_now           -> 创建时,自动生成时间
            auto_now_add       -> 更新时,自动更新为当前时间
            
                # obj = UserGroup.objects.filter(id=1).update(caption='CEO')
                # obj = UserGroup.objects.filter(id=1).first()
                # obj.caption = "CEO"
                # obj.save()
                
            choices              -> django admin中显示下拉框,避免连表查询
            blank             -> django admin是否可以为空
            verbose_name      -> django admin显示字段中文
            editable          -> django admin是否可以被编辑
            error_messages    -> 错误信息欠
            help_text         -> django admin提示
            validators          -> django form ,自定义错误信息(欠)
            
            
            创建 Django 用户:python manage.py createsuperuser
            
            
            
            
    2. 根据类对数据库表中的数据进行各种操作
    
        一对多:
        
            a. 外检
            b. 
                外键字段_id
            c.
                models.tb.object.create(name='root', user_group_id=1)
                
            d. 
                
                userlist = models.tb.object.all()
                for row in userlist:
                    row.id
                    row.user_group_id
                    row.user_group.caption
                    
                    
    =================== 作业:用户管理 ====================
    1、用户组的增删改查
    2、用户增删该查
        - 添加必须是对话框
        - 删除必须是对话框
        - 修改,必须显示默认值
        
    3、比较好看的页面
    
    4、预习:
        http://www.cnblogs.com/wupeiqi/articles/5246483.html

1、Django请求的生命周期
        路由系统 -> 试图函数(获取模板+数据=》渲染) -> 字符串返回给用户
        
2、路由系统
        /index/                ->  函数或类.as_view()
        /detail/(d+)          ->  函数(参数) 或 类.as_view()(参数)
        /detail/(?P<nid>d+)   ->  函数(参数) 或 类.as_view()(参数)
        /detail/               ->  include("app01.urls")
        /detail/    name='a1'  ->  include("app01.urls")
                               - 视图中:reverse
                               - 模板中:{% url "a1" %}
                               
3、视图
    FBV:函数
        def index(request,*args,**kwargs):
            ..
    
    CBV:类
        class Home(views.View):
            
            def get(self,reqeust,*args,**kwargs):
                ..
                
    获取用户请求中的数据:
        request.POST.get
        request.GET.get
        reqeust.FILES.get()
        
        # checkbox,
        ........getlist()
        
        request.path_info
        
        
        文件对象 = reqeust.FILES.get()
        文件对象.name
        文件对象.size
        文件对象.chunks()
        
        # <form 特殊的设置></form>
        
    给用户返回数据:
        render(request, "模板的文件的路径", {'k1': [1,2,3,4],"k2": {'name': '张扬','age': 73}})
        redirect("URL")
        HttpResponse(字符串)
        
    
4、模板语言
        render(request, "模板的文件的路径", {'obj': 1234, 'k1': [1,2,3,4],"k2": {'name': '张扬','age': 73}})
    
    <html>
    
    <body>
        <h1> {{ obj }} </h1>
        <h1> {{ k1.3 }} </h1>
        <h1> {{ k2.name }} </h1>
        {% for i in k1 %}
            <p> {{ i }} </p>
        {% endfor %}
        
        {% for row in k2.keys %}
            {{ row }}
        {% endfor %}
        
        {% for row in k2.values %}
            {{ row }}
        {% endfor %}
        
        {% for k,v in k2.items %}
            {{ k }} - {{v}}
        {% endfor %}
        
    </body>
    </html>
    
5、ORM
    a. 创建类和字段
        class User(models.Model):
            age = models.IntergerFiled()
            name = models.CharField(max_length=10)#字符长度
            
        Python manage.py makemigrations
        python manage.py migrate
        
        # settings.py 注册APP
        
    b. 操作
        增
            models.User.objects.create(name='qianxiaohu',age=18)
            dic = {'name': 'xx', 'age': 19}
            models.User.objects.create(**dic)

            obj = models.User(name='qianxiaohu',age=18)
            obj.save()
        删
            models.User.objects.filter(id=1).delete()
        改
            models.User.objects.filter(id__gt=1).update(name='alex',age=84)
            dic = {'name': 'xx', 'age': 19}
            models.User.objects.filter(id__gt=1).update(**dic)
        查
            models.User.objects.filter(id=1,name='root')
            models.User.objects.filter(id__gt=1,name='root')
            models.User.objects.filter(id__lt=1)
            models.User.objects.filter(id__gte=1)
            models.User.objects.filter(id__lte=1)
            
            models.User.objects.filter(id=1,name='root')
            dic = {'name': 'xx', 'age__gt': 19}
            models.User.objects.filter(**dic)
            
            v1 = models.Business.objects.all()
            # QuerySet ,内部元素都是对象
            
            # QuerySet ,内部元素都是字典
            v2 = models.Business.objects.all().values('id','caption')
            # QuerySet ,内部元素都是元组
            v3 = models.Business.objects.all().values_list('id','caption')
        
            # 获取到的一个对象,如果不存在就报错
            models.Business.objects.get(id=1)
            对象或者None = models.Business.objects.filter(id=1).first()

            外键:
                v = models.Host.objects.filter(nid__gt=0)
                v[0].b.caption  ---->  通过.进行跨表

        
        外键:
            class UserType(models.Model):
                caption = models.CharField(max_length=32)
              id  caption
            # 1,普通用户
            # 2,VIP用户
            # 3, 游客
                
            class User(models.Model):
                age = models.IntergerFiled()
                name = models.CharField(max_length=10)#字符长度
                # user_type_id = models.IntergerFiled() # 约束,
                user_type = models.ForeignKey("UserType",to_field='id') # 约束,
        
              name age  user_type_id     

    position:fixed absolute relative

    Ajax
    
        $.ajax({
            url: '/host',
            type: "POST",
            data: {'k1': 123,'k2': "root"},
            success: function(data){
                // data是服务器端返回的字符串
                var obj = JSON.parse(data);
            }
        })
        
    
        建议:永远让服务器端返回一个字典
        
        return HttpResponse(json.dumps(字典))
        
            
多对多:
    创建多对多:
        方式一:自定义关系表
            class Host(models.Model):
                nid = models.AutoField(primary_key=True)
                hostname = models.CharField(max_length=32,db_index=True)
                ip = models.GenericIPAddressField(protocol="ipv4",db_index=True)
                port = models.IntegerField()
                b = models.ForeignKey(to="Business", to_field='id')
            # 10
            class Application(models.Model):
                name = models.CharField(max_length=32)
            # 2
            
            class HostToApp(models.Model):
                hobj = models.ForeignKey(to='Host',to_field='nid')
                aobj = models.ForeignKey(to='Application',to_field='id')
                
            # HostToApp.objects.create(hobj_id=1,aobj_id=2)
                
                
                
        方式二:自动创建关系表
            class Host(models.Model):
                nid = models.AutoField(primary_key=True)
                hostname = models.CharField(max_length=32,db_index=True)
                ip = models.GenericIPAddressField(protocol="ipv4",db_index=True)
                port = models.IntegerField()
                b = models.ForeignKey(to="Business", to_field='id')
            # 10
            class Application(models.Model):
                name = models.CharField(max_length=32)
                r = models.ManyToManyField("Host")
                
            无法直接对第三张表进行操作
            
            obj = Application.objects.get(id=1)
            obj.name
            
            # 第三张表操作
            obj.r.add(1)
            obj.r.add(2)
            obj.r.add(2,3,4)
            obj.r.add(*[1,2,3,4])
            
            obj.r.remove(1)
            obj.r.remove(2,4)
            obj.r.remove(*[1,2,3])
            
            obj.r.clear()
            
            obj.r.set([3,5,7])
            
            # 所有相关的主机对象“列表” QuerySet
            obj.r.all()

s14day21

上节内容回顾:
    1、请求周期
        url> 路由 > 函数或类 > 返回字符串或者模板语言?
        
        Form表单提交:
            提交 -> url > 函数或类中的方法 
                                - ....
                                HttpResponse('....')
                                render(request,'index.html')
                                redirect('/index/')
             用户  <    <  返回字符串
             (当接受到redirect时)自动发起另外一个请求
             --> url   .....
             
        Ajax:
            $.ajax({
                url: '/index/',
                data: {'k': 'v', 'list': [1,2,3,4], 'k3': JSON.stringfy({'k1': 'v'}))}, $(form对象).serilize() 
                type: 'POST',
                dataType: 'JSON':
                traditional: true,
                success:function(d){
                    location.reload()              # 刷新
                    location.href = "某个地址"     # 跳转
                }
            })
            提交 -> url -> 函数或类中的方法 
                            HttpResponse('{}')
                            render(request, 'index.html', {'name': 'v1'})
                            <h1>{{ name }}</h1> --> 
                            <h1>v1</h1>
                            
                            XXXXXXX redirect...
            用户    <<<<<  字符串
        
    
    2、路由系统URL
        a. /index/                               ->  函数或类
        b. /index/(d+)                            ->  函数或类
        c. /index/(?P<nid>d+)                   ->  函数或类
        d. /index/(?P<nid>d+) name='root'          ->  函数或类
            reverse()
            {% url 'root' 1%}
        e. /crm/    include('app01.urls')        -> 路由分发
        
        f. 默认值
            url(r'^index/', views.index, {'name': 'root'}),
        
            def index(request,name):
                print(name)
                return HttpResponse('OK')
    
        g. 命名空间
            
            /admin/    include('app01.urls',namespace='m1')
            /crm/      include('app01.urls',namespace='m1')
            
            app01.urls
            /index/    name = 'n1'
            
            
            reverser('m1:n1')
    
    3、
        def func(request):
            request.POST
            request.GET
            request.FILES
            request.getlist
            request.method
            request.path_info
            
            return render,HttpResponse,redirect
            
    4、
        render(request, 'index.html')
        # for
        # if
        # 索引.   keys  values items    all
        
    5class User(models.Model):
            username = models.CharField(max_length=32)
            email = models.EmailField()
            
        有验证功能
            Django Admin
        无验证功能:
            User.objects.create(username='root',email='asdfasdfasdfasdf')
            User.objects.filter(id=1).update(email='666')
        
        
        
        class UserType(models.Model):
            name = models.CharField(max_length=32)
        
        
        class User(models.Model):
            username = models.CharField(max_length=32)
            email = models.EmailField()
            user_type = models.ForeignKey("UserType")
        
        user_list = User.objects.all()
        for obj user_list:
            obj.username,obj.email,obj.user_type_id,obj.user_type.name,obj.user_type.id
        
        user = User.objects.get(id=1)
        user.
        
        User.objects.all().values("username","user_type__name",)
        
        
        
        class UserType(models.Model):
            name = models.CharField(max_length=32)
        
        
        class User(models.Model):
            username = models.CharField(max_length=32)
            email = models.EmailField()
            user_type = models.ForeignKey("UserType")
            m = models.ManyToMany('UserGroup')
            
            
        class UserGroup(models.Model):
            name = ....
            
            
        obj = User.objects.get(id=1)
        obj.m.add(2)
        obj.m.add(2,3)
        obj.m.add(*[1,2,3])
        
        obj.m.remove(...)
        
        obj.m.clear()
        
        
        obj.m.set([1,2,3,4,5])
        
        # 多个组,UserGroup对象
        obj.m.all()
        obj.m.filter(name='CTO')
        
        
知识点:
    URL
        - 两个
    Views
        - 请求的其他信息
        from django.core.handlers.wsgi import WSGIRequest
        request.environ
        request.environ['HTTP_USER_AGENT']
        - 装饰器
            FBV:
                def auth(func):
                    def inner(reqeust,*args,**kwargs):
                        v = reqeust.COOKIES.get('username111')
                        if not v:
                            return redirect('/login/')
                        return func(reqeust, *args,**kwargs)
                    return inner
        
            CBV:
                from django import views
                from django.utils.decorators import method_decorator

                @method_decorator(auth,name='dispatch')
                class Order(views.View):

                    # @method_decorator(auth)
                    # def dispatch(self, request, *args, **kwargs):
                    #     return super(Order,self).dispatch(request, *args, **kwargs)

                    # @method_decorator(auth)
                    def get(self,reqeust):
                        v = reqeust.COOKIES.get('username111')
                        return render(reqeust,'index.html',{'current_user': v})

                    def post(self,reqeust):
                        v = reqeust.COOKIES.get('username111')
                        return render(reqeust,'index.html',{'current_user': v})
    Templates
        - 母版...html
            extends
            include
        - 自定义函数
            simple_tag
                a. app下创建templatetags目录
                b. 任意xxoo.py文件
                c. 创建template对象 register
                d. 
                    @register.simple_tag
                    def func(a1,a2,a3....)
                        return "asdfasd"
                e. settings中注册APP
                f. 顶部 {% load xxoo %}
                g. {% 函数名 arg1 arg2 %}
                缺点:
                    不能作为if条件
                优点:
                    参数任意
            filter
                a. app下创建templatetags目录
                b. 任意xxoo.py文件
                c. 创建template对象 register
                d. 
                    @register.filter
                    def func(a1,a2)
                        return "asdfasd"
                e. settings中注册APP
                f. 顶部 {% load xxoo %}
                g. {{ 参数1|函数名:"参数二,参数三" }} {{ 参数1|函数名:数字 }}
                缺点:
                    最多两个参数,不能加空格
                优点:
                    能作为if条件
            
    分页(自定义的分页)
        
        XSS:
            {{ page_str|safe }}
            
            mark_safe(page_str)
    
    cookie
        客户端浏览器上的一个文件
            {"user": 'dachengzi'}
    
    session :装饰器
        
    
    Models
        - 一大波操作
        
    Form验证
        -
    缓存
    中间件
    信号
    CSRF
    Admin/ModelForm
        
作业:
    主机管理:
        1、单表操作
        2、一对多
        3、多对多
        要求:
            a. 删除对话框
            b. 修改,添加新URL
            c. 基于cookie进行用户认证
            d. 定制显示个数
            e. 分页
    预习:
        Form: http://www.cnblogs.com/wupeiqi/articles/6144178.html
        Model:http://www.cnblogs.com/wupeiqi/articles/6216618.html

day22

知识点概要
    - Session
    - CSRF
    - Model操作
    - Form验证(ModelForm)
    - 中间件
    - 缓存
    - 信号


内容详细:

1. Session
    基于Cookie做用户验证时:敏感信息不适合放在cookie中
    

    a. Session原理
        Cookie是保存在用户浏览器端的键值对
        Session是保存在服务器端的键值对
    
    b. Cookie和Session对比
    
    c. Session配置(缺少cache)
    
    d. 示例:实现两周自动登陆
            - request.session.set_expiry(60*10)
            - SESSION_SAVE_EVERY_REQUEST = True

    PS: cookie中不设置超时时间,则表示关闭浏览器自动清除
    
    
    - session依赖于cookie
    - 服务器session
        request.session.get()
        request.session[x] = x
        
        request.session.clear()
        
    - 配置文件中设置默认操作(通用配置):
        SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
        SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
        SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
        SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
        SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
        SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
        SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
        # set_cookie('k',123)
        SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)

    - 引擎的配置
    
2. CSRF
    a. CSRF原理

    b. 无CSRF时存在隐患

    c. Form提交(CSRF)

    d. Ajax提交(CSRF)
       CSRF请求头 X-CSRFToken
       
6. 中间件

7. 缓存
    5种配置
    3种应用:
        全局
        视图函数
        模板

8. 信号
    - 内置信号
    - 自定义
         - 定义信号
         - 出发信号
         - 信号中注册函数
    
3. Model操作
    
    a. 字段类型 + 参数

    b. 连表字段 + 参数

    c. Meta

    d. SQL操作:
        - 基本增删改查
        - 进阶操作
        - 正反查询
        - 其他操作

    e. 验证(弱)

4. Form操作
    完成:
        - 验证用户请求
        - 生成HTML
          (保留上一次提交的数据)
        
    自定义:
        -- 字段(校验)
        - 插件(生成HTML)
        
    初始化操作:
        

============= 作业:xxxoo管理 =============
用户验证:session
新URL:Form验证
中间件:IP过滤
信号:记录操作
CSRF:
    
    
    a. Form验证用户请求

    b. Form生成HTML

    c. Form字段详细(自定义字段,Model...) + 插件

    d. 自定义验证(钩子以及__all__)

    e. 注册示例:
         用户名、密码、邮箱、手机号(RegexValidator或RegexField)、性别、爱好、城市
    
    f. 初始化值

5. ModelForm

    a. Model+Form功能集合

    b. save

    c. save + save_m2m

    Model
        - 数据库操作
        - 验证
        class A(MOdel):
            user = 
            email = 
            pwd = 
        
    Form
        - class LoginForm(Form): 
            email = fields.EmailField()
            user = 
            pwd = 
            
        - is_valid -> 每一个字段进行正则(字段内置正则)+clean_字段 -> clean(__all__)  -> _post_clean
        - cleand_data
        - error
    --------> 推荐 <---------
        
一、ModelForm
    参考博客:
        http://www.cnblogs.com/wupeiqi/articles/6229414.html
    
    Model + Form => 验证 + 数据库操作
    - class LoginModelForm(xxxxx): 
         利用model.A中的字段
         
         
    1. 生成HTML标签:class Meta: ...
    2. mf = xxxModelForm(instance=ModelObj)
    3. 额外的标签, is_rmb = Ffields.CharField(widget=Fwidgets.CheckboxInput())
    4. 各种验证 is_valid() -> 各种钩子...
    5.     mf.save()
        # 或
        instance = mf.save(False)
        instance.save()
        mf.save_m2m()
    

二、Ajax
    参考博客:
        http://www.cnblogs.com/wupeiqi/articles/5703697.html
    
    原生
        
    jQuery
    
    伪Ajax操作
    
    时机:
        如果发送的是【普通数据】 -> jQuery,XMLHttpRequest,iframe
    
三、文件上传(预览)
    
    - Form提交
    - Ajax上传文件
    
    时机:
        如果发送的是【文件】 -> iframe,jQuery(FormData),XMLHttpRequest(FormData),
    

四、图片验证码 + Session
    
    - session
    - check_code.py(依赖:Pillow,字体文件)
    - src属性后面加?

五、CKEditor,UEEditor,TinyEditor,KindEditor(***)
    参考博客:
        http://www.cnblogs.com/wupeiqi/articles/6307554.html
        
    - 基本使用
    - 文件上传,多文件上传,文件空间管理
    - XSS攻击(过滤的函数或类) 下节课说...

仅供学习使用

Django创建项目时应该要做的几件事
安装 django 1.11.14
pip install django==1.11.14 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com

卸载 django 1.11.14
pip uninstall django==1.11.14
创建 django 项目
django-admin startproject 项目名

django-admin startproject study
创建 app,到 study 项目名称目录下输入
python manage.py startapp app名称

python manage.py startapp app01
在 C:Users47311AppDataLocalProgramsPythonPython38Libsite-packagesdjangocontribadmin 目录下的

widgets.py 中的152行删除 , 逗号

在 pycharm 中打开 django 项目工程

 

 

 

创建好的项目工程


配置创建好的 app 应用(根据创建app时的名称进行添加到 INSTALLED_APPS 中)


新建文件夹命名为 templates -> 创建模板

 

 

在 项目的 settings 中进行注册 templats ,本文中的 settings 均是指 项目下的 settings 

 

 

在 TEMPLATES 下的 DIRS 中 添加 

os.path.join(BASE_DIR,'templates')

创建静态文件夹 static ,步骤如上所示

 

 

在 settings 中进行注册 ,在最后一行位置添加 

STATICFILES_DIRS = (
    os.path.join(BASE_DIR,'static'),
)

修改页面显示的语言为汉语

LANGUAGE_CODE 修改为 
LANGUAGE_CODE = 'zh-hans'

修改时间 TIME_ZONE 为北京时间

TIME_ZONE = 'Asia/Shanghai'

 


运行 django 项目命令 ,启动也可以选择右上角的三角符号

python manage.py runserver

运行成功界面,django的版本很多,如果您成功了,请继续努力.

 django 命令行命令

django-admin startproject 项目名

django-admin startproject 

python manage.py makemigrations

python manage.py migrate

python manage.py startapp app名称

python manage.py startapp 

启动运行 django 

python manage.py runserver
项目下的 urls 篇
urlpatterns = [ ] 其中主要是包含有各个 app 的路由
示例:

url(r'^users/', include('users.urls', namespace='users')),

url(r'^admin/', admin.site.urls),
settings 中的基础知识
INSTALLED_APPS = [ ] 存放创建好的app名称(app注册)

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'users',
    '创建好的app名称',
]
MIDDLEWARE = [] 中间件
TEMPLATES = [ ] 模板文件 

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ['templates'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

'DIRS'可以修改为 

'DIRS': [os.path.join(BASE_DIR, 'templates')],
DATABASES  = { } 数据库 配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '数据库',
        'USER': '用户名',
        'PASSWORD': '密码',
        'CHARSET': '字符集',
        'HOST': 'IP地址',
        'PORT': '端口',
    }
}

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'webshop',
        'USER': 'root',
        'PASSWORD': 'root',
        'CHARSET': 'UTF-8',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}
设置中文

LANGUAGE_CODE = 'zh-hans'
时间显示为北京时间

TIME_ZONE = 'Asia/Shanghai'
配置 static 静态目录

STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR,'static'),
)

暂时还没有接触到的点(慎用)

SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'

# hash加密使用的盐值
SALT_KEY = "Hello"

LOGIN_URL = '/users/login'

项目的 __init__ 文件中添加的内容

import pymysql

pymysql.install_as_MySQLdb()

app 的urls(创建的.py文件)

导入 views 

from . import views

urlpatterns = [
    url(r'^login/$', views.user_login, name='user_login'),
    url(r'^register/$', views.register, name='register'),
]
使用 (?P<views 中的函数参数名称>d+) 获取传递进来的参数给 views 中函数的参数

urlpatterns = [
    url(r'^(?P<s_id>d+)/detail_store', views.detail_store, name='detail_store'),
    url(r'^(?P<s_id>d+)/(?P<status>d+)/status_store', views.status_store, name='status_store'),
]
urlpatterns = [
    url(r'^(?P<number>d+)/(?P<goods_id>d+)/shop_into/$', views.shop_into, name='shop_into'),
    url(r'^list_car/$', views.list_car, name='list_car'),
    url(r'^(?P<shopcar_id>d+)/del_car/$', views.del_car, name='del_car'),
]
urlpatterns = [
    url(r'^order_confirm/$', views.order_confirm, name='order_confirm'),
    url(r'^order_pay/$', views.order_pay, name='order_pay'),
    url(r'^order_done/$', views.order_done, name='order_done'),
    url(r'^order_list/$', views.order_list, name='order_list'),
    url(r'^(?P<order_id>d+)/order_desc/$', views.order_desc, name='order_desc'),

]
url(r'^路由地址/$', views.函数名, name='名称'),

url(r'^(?P<函数参数名称>d+)/路径名/$', views.函数名, name='名称'),
关于路由系统,这里只是写出了最简单的写法,此处只是根据读程序获取到的部分知识

app 的 models,为 views 作基础,views在获取到urls中的请求后,会调用一些方法
创建主键 -> 1.11.14 自动创建 id 列 
在外键关联时,自动加上 _id 名称
 
id = models.AutoField(primary_key=True)
创建字符串 name 列 ,使用 models.CharField 

country = models.CharField(max_length=255, default='中国',verbose_name='城市')

area = models.CharField(max_length=50, verbose_name='收货人县/区/')
使用 bool 类型

数据字段名称 = models.BooleanField(default=False, verbose_name='xxx')

is_default = models.BooleanField(default=False, verbose_name='是否是默认地址')
int 类型 , 使用 models.IntegerField

age = models.IntegerField(default='20', verbose_name='用户年龄')

status = models.IntegerField(default=0, verbose_name='店铺状态')

goods_count = models.IntegerField(verbose_name='购买数量')
image 图片类型 使用 models.ImageField

变量名 = models.ImageField(upload_to='图片路径', default='图片名', verbose_name='名称')
变量名 = models.ImageField(upload_to='图片路径')


logo = models.ImageField(upload_to='static/images/logo', default='static/images/logo/goods-style1.png', verbose_name='商品类型图标')

path = models.ImageField(upload_to='static/images/goods', default='static/images/goods/default.jpg', verbose_name='商品图片')

goods_image = models.ImageField(upload_to='static/images/goods')

cover = models.ImageField(upload_to='static/images/store/', default='static/images/store/default.jpg', verbose_name='店铺封面')

header = models.ImageField(upload_to='static/images/headers', default='static/images/headers/default.jpg', verbose_name='用户头像')
text 描述 使用 models.TextField
变量名 = models.TextField(verbose_name= '名称')
变量名 = models.TextField(null=True, blank=True,verbose_name= '名称')

intro = models.TextField(verbose_name='商品类别描述')

intro = models.TextField(null=True, blank=True, verbose_name='商品图片描述')
float 浮点数类型,使用 models.FloatField
变量名 = models.FloatField(verbose_name='名称')
变量名 = models.FloatField(default=0.00, verbose_name='名称')

price = models.FloatField(verbose_name='商品价格')

allMoney = models.FloatField(default=0.00, verbose_name='总计')
datetime 使用 models.DateTimeField
变量名 = models.DateTimeField(auto_now_add=True, verbose_name='名称')

openTime = models.DateTimeField(auto_now_add=True, verbose_name='开店时间')

注:可以添加 datetime.now 用来在创建时,指定当前时间
foreignkey 外键 , 使用 models.ForeignKey

变量名 = models.ForeignKey(类名, null=True, blank=True, on_delete=models.CASCADE, verbose_name='名称')

parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE, verbose_name='父级地址')
from app名称.models import 类名

变量名 = models.ForeignKey(类名, on_delete=models.CASCADE, verbose_name='名称')
注:类名可以是外部导入或本models.py中创建的类名

from users.models import User

user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='地址所属')
一个models 类可以存在两个外键

goodsStore = models.ForeignKey(类名, on_delete=models.CASCADE, verbose_name='名称')
goodsType = models.ForeignKey(类名, on_delete=models.CASCADE, verbose_name='名称')


from store.models import Store
goodsStore = models.ForeignKey(Store, on_delete=models.CASCADE, verbose_name='商品所属店铺')
goodsType = models.ForeignKey(GoodsType, on_delete=models.CASCADE, verbose_name='商品类型')
从 django.contrib.auth.models 导入 User

from django.contrib.auth.models import User

user = models.ForeignKey(User, on_delete=models.CASCADE)
一对一 使用 models.OneToOneField
变量名 = models.OneToOneField(User, on_delete=models.CASCADE)

user = models.OneToOneField(User, on_delete=models.CASCADE)
在这里补充一点,字段还存在一对多和多对多

app 中的 views 
def 函数名(request):
    代码块
    return 语句(是否存在参数)

def 函数名(request,参数(一个或多个)):
    代码块
    return 语句(是否存在参数)

@装饰器(一个或多个)
def 函数名(request):
    代码块
    return 语句(是否存在参数)

@装饰器(一个或多个)
def 函数名(request,参数(一个或多个)):
    代码块
    return 语句(是否存在参数)
关于def 函数定义时,request 后面的参数
在进行路由分发时,使用 
url(r'^(?P<g_id>d+)/goods_detail/$', views.goods_detail, name='goods_detail'),

进行 get 请求传递进来的参数会给 g_id ,因此在 goods_detail 函数中要设置一个参数名为 g_id 

def goods_detail(request, g_id):
    代码
注:有多少个?P<参数名> 就设置多少个参数,用来接收
代码块中可以使用到很多知识,此处只是该项目使用到的基础

request.method 
判断进行的哪一种请求方式,GET还是POST

if request.method == 'GET':
    pass
elif request.method == 'POST':
    pass
else:
    pass
models.类名.objects.filter(表中字段(user)=request.user)
filter 主要是用来过滤,使用了filter 之后还可以继续使用 filter进行过滤

address_list = models.Address.objects.filter(user=request.user)

对于使用了 filter 方法 的对象,可以使用 len 进行判断,是否已经存在

sto = models.Store.objects.filter(name=name)
if len(sto) == 1:
return render(request, 'store/store_add.html', {"msg": "商铺名称已存在,请重新输入"})
获取 post 方式提交的数据
request.POST['名称']

recv_name = request.POST['recv_name']

html 中数据如下,让name的值于名称相对应即可
<input type="text" name="recv_name" id="recv_name" autocomplete="off">

name = request.POST['name'].strip()
在进行获取数据时,可以添加 strip 进行字符串操作
对于 filter 获取到的数据可以进行遍历
address_list = models.Address.objects.filter(user=request.user)
并且遍历的元素对象具有 save 方法 可以修改字段
Address 是类名,user , is_default 是 Address 表中的字段

from . import models

address_list = models.Address.objects.filter(user=request.user)
for addr in address_list:
    addr.is_default = False
    addr.save()

使用 __in 时,可以直接写明在某一个变量中 [0,1]
stores = models.Store.objects.filter(user=request.user, status__in=[0, 1])
添加表的一行数据
括号中 = 前面的都是表中的字段,后面是对应的值
使用 save 进行保存

变量 = models.类名(字段1 = 值1, 字段2 = 值2, user=request.user)
变量 .save()


address = models.Address(recv_name=recv_name, recv_tel=recv_tel, province=province, city=city, area=area,
                                     street=street, desc=desc, is_default=True, user=request.user)

address.save()

goods = models.Goods(name=name, price=price, stock=stock, desc=desc, goodSize=goodSize, goodsType=goodsType,goodsStore=store )
goods.save()



id 自增列不用添加
在使用 filter 获取数据后,使用 order_by 进行排序

from app名称.models import 类名
变量名 = 类名.objects.filter(user=request.user).order_by('名称')


shop_cars = ShopCar.objects.filter(user=request.user).order_by('-createTime')
在 filter 中使用 =
变量名 = 类名.objects.filter(字段名=值)

goods_type1 = GoodsType.objects.filter(pk=1001)
在 filter 中使用 __in
变量名 = 类名.objects.filter(字段名__in=值)
变量名 = 类名.objects.filter(字段名__in=值)[:2]

goods1_list = Goods.objects.filter(goodsType__in=goods_type1_2)[:4]
在 filter 中使用 __isnull
变量名 = 类名.objects.filter(字段名__isnull=True)


allGoodsType = GoodsType.objects.filter(parent__isnull=True)
文件 files , 具体请查阅更多资料

变量名 = request.FILES['名称']

path = request.FILES['path']

cover = request.FILES['cover']
cover 为 html 中的 name 值 <input name="cover" type="file" ... >
使用 .get 获取数据

变量 = 类名.objects.get(字段=变量或值)

store_id = request.POST['goodsStore']
store = Store.objects.get(pk=store_id)
是否带有 models 主要看导入包的方式
from . import models

type2 = request.POST['type2']
goodsType = models.GoodsType.objects.get(pk=type2)
利用获取到的对象的字段属性进行赋值

变量 = models.Goods.objects.get(字段名1=参数)
变量= goods.字段名2
store = models.类名.objects.get(字段名1=字段名2)


goods = models.Goods.objects.get(pk=g_id)
goodsStore_id = goods.goodsStore_id
store = models.Store.objects.get(pk=goodsStore_id)

注:
字段名根据实际需要进行修改
获取所有数据 使用 all 
变量名 = models.类名.objects.all()

all_goods = models.Goods.objects.all()
获取 GET 参数
变量名1 = request.GET['名称']

parent_id = request.GET['parent_id']

进行查找数据
变量名2 = models.类名.objects.filter(字段=变量名1)

type2 = models.GoodsType.objects.filter(parent=parent_id)
使用 getlist 获取多个数据

变量 = request.POST.getlist('名称')

shopcar_id_list = request.POST.getlist('buy_goods_id')

进行查找数据
变量2 = app名.models.类名.objects.filter(字段名__in=变量)
shopcar_list = shopcar.models.ShopCar.objects.filter(pk__in=shopcar_id_list)
关于字段中 user=request.user 的理解
MyOrder 中的 user 是 User 的外键,所以在使用时,要注意传递的属性还是一整个对象

my_order = models.MyOrder(user=request.user, address=addr, total=total)

user = models.ForeignKey(User, on_delete=models.CASCADE)
使用 字段_set 可以获取到外键的表的字段,具体详情请查阅更多资料

此处仅给出部分示例

for sc_id in shopcar_list:
    shopcart = shopcar.models.ShopCar.objects.get(pk=sc_id)
    order_item = models.MyOrderItem(goods_image=shopcart.goods.goodsimage_set.first().path,
                                    goods_name=shopcart.goods.name,
                                    goods_price=shopcart.goods.price,
                                    goods_count=shopcart.number,
                                    goods_money=shopcart.allMoney,
                                    my_order=my_order)
    order_item.save()
    total += shopcart.allMoney
my_order.total = total
my_order.save()
get 获取写法,比之前的更深入一些

@login_required
@require_GET
def shop_into(request, number, goods_id):
    goods = Goods.objects.get(pk=goods_id)
    user = request.user
    try:
        shop_car = models.ShopCar.objects.get(user=user, goods=goods)
        shop_car.number += int(number)
        shop_car.allMoney = shop_car.number*goods.price
        shop_car.save()
    except:
        shop_car = models.ShopCar(goods=goods, number=number, user=user)
        shop_car.allMoney = int(shop_car.number)*goods.price
        shop_car.save()
    return redirect(reverse('shopcar:list_car'))

在使用 get 方法时,其中的 = 左侧依旧为字段名,=右侧的为get 获取到的对象,user 为 request.user

goods = Goods.objects.get(pk=goods_id)
user = request.user
shop_car = models.ShopCar.objects.get(user=user, goods=goods)

request.user 拥有 id 属性

使用 get 可以获取到字段进行参与表达式运算

shop_car.allMoney = shop_car.number*goods.price
删除数据 使用 delete()
shopcar = models.ShopCar(pk=shopcar_id, user=user)
shopcar.delete()
使用 int 进行转换

status = models.IntegerField(default=0, verbose_name='店铺状态')


store = models.Store.objects.get(id=s_id)
store.status = int(status)
获取 session 使用 request.session

变量名 = request.session["名称"]
示例:

if code.lower() != request.session["code"].lower():
    return render(request, "users/user_login.html", {"msg": "验证码错误!!"})
使用 authenticate

from django.contrib.auth import authenticate
user = authenticate(username=username, password=password1)

password1 = utils.encryption(password)

# 密码加密
def encryption(key):
    pwd = hmac.new(key.encode('utf-8'), settings.SALT_KEY.encode('utf-8'), 'MD5')
    return pwd.hexdigest()

此时的 user 拥有 is_active 属性,判断是否登录状态
if user is not None:
    if user.is_active:
        login(request, user)
        try:
            return redirect(next_url)
        except:
            return redirect("/")
    else:
        return render(request, "users/user_login.html", {"msg": "您的账号已被锁定,请联系管理员"})
else:
    return render(request, "users/user_login.html", {"msg": "用户名或者密码错误"})
导入 User
from django.contrib.auth.models import User

user = User.objects.create_user(username=username, password=password)

user.save()
代码块介绍之后,进行return返回
return render(request, 'templates 下的文件夹名称/文件名.html', {'名称': 值})


return render(request, 'address/address_add.html', {'address_list': address_list})

可以存在多个参数,goods 为在app目录下templates 中的 goods 文件夹
return render(request, 'goods/goods_show.html', {'goods': goods, 'store': store, 'nums':nums})
return redirect(reverse('名称1:值1', kwargs={'参数名': 值}))
html 中的数据
<a href="{% url '名称1:值1' 空格 参数名 %}">内容</a>

store_id = request.POST['goodsStore']

return redirect(reverse('store:detail_store', kwargs={'s_id': store_id}))

在这里 'store:detail_store' 为 反向解析

<a href="{% url 'store:detail_store' store.id %}">查看详情</a>
from django.core.serializers import serialize

type1 = models.GoodsType.objects.filter(parent=parent_id)
return HttpResponse(serialize('json', type1))
#转换成json类型的字符串
return redirect(reverse('shopcar:list_car'))


<a href="{% url 'shopcar:list_car'%}" style="border: none;color: #00b7ee; 100px;height: 40px" >返回购物车</a>
from io import BytesIO

def code(request):
    img, msg = utils.create_code()
    f = BytesIO()
    img.save(f, "PNG")
    # 将验证码的值存储到session
    request.session["code"] = msg
    return HttpResponse(f.getvalue(), "image/png")

utils.py 文件,自己创建,如果需要可以复制粘贴
import hmac
import string
import random
from PIL import Image, ImageDraw, ImageFont
from django.conf import settings



# 密码加密
def encryption(key):
    pwd = hmac.new(key.encode('utf-8'), settings.SALT_KEY.encode('utf-8'), 'MD5')
    return pwd.hexdigest()


# 验证码
def getRandomChar(count=4):
    # 生成随机字符串
    # string模块包含各种字符串,以下为小写字母加数字
    ran = string.ascii_lowercase + string.ascii_uppercase + string.digits
    char = ''
    for i in range(count):
        char += random.choice(ran)
    return char


# 返回一个随机的RGB颜色
def getRandomColor():
    return random.randint(50, 150), random.randint(50, 150), random.randint(50, 150)


def create_code():
    # 创建图片,模式,大小,背景色
    img = Image.new('RGB', (120, 30), (255, 255, 255))
    # 创建画布
    draw = ImageDraw.Draw(img)
    # 设置字体
    font = ImageFont.truetype('ARIALUNI.TTF', 25)

    code = getRandomChar()
    # 将生成的字符画在画布上
    for t in range(4):
        draw.text((25*t+7, 0), code[t], getRandomColor(), font)

    # 生成干扰点 增加识别的难度
    for _ in range(random.randint(99, 110)):
        # 位置,颜色
        draw.point((random.randint(0, 120), random.randint(0, 30)), fill=getRandomColor())
    # 生成干扰线 增加识别的难度
    for _ in range(random.randint(8, 15)):
        begin = random.randint(0, 120), random.randint(0, 50)
        end = random.randint(0, 120), random.randint(0, 50)
        draw.line([begin, end], fill=getRandomColor())

    # 使用模糊滤镜使图片模糊
    # img = img.filter(ImageFilter.BLUR)
    return img, code

HTML 文件
此处只例举一些基本语句,具体用法请查阅相关资料
{% block 名称 %}{% endblock %}
进行继承模板
{% extends '名称.html' %}
{% csrf_token %}

服务器返回页面的同时向前端返回一串随机字符

post提交时服务器会验证这串字符来确保用户是在服务端返回的表单页面中提交的数据
<tbody>
{% for addr in address_list %}
<tr>
    <td>{{addr.字段1}}</td>
    <td>{{addr.字段2}}</td>
    <td>{{addr.字段3}}</td>
    <td>
        {% if addr.is_default %}
        默认地址
        {% endif %}
    </td>
</tr>
{% empty %}
<tr>提示信息</tr>
{% endfor %}
</tbody>
{% if request.user.username %}
    html 语句
{% else %}
    html 语句
{% endif %}
{{request.user.userinfo.nickname}}
<form action="{%url 'orders:order_done' %}" method="post">
<input type="hidden" name="sc" value="{{sc.id}}">
<span>{{shopcar.number}}</span>
下单时间:{{order.order_time|date:'Y-m-d G:i:s'}}<br>
{% if store.status == 0 %}
<span style="font-size: 16px">店铺状态:正在营业</span>
{% elif store.status == 1 %}
<span style="font-size: 16px">店铺休息</span>
{% endif %}
{{goods.desc|truncatechars:22}}
截取前22个字符
{% for t in type1 %}
<option value="{{t.id}}" >{{t.name}}</option>
{% endfor %}

html 下还有很多的用法,此处仅列举出了这些

django 项目获取链接
链接:https://pan.baidu.com/s/1oWcHHbSR0JHmqr9qCzZGwA 提取码:Hany

 

原文地址:https://www.cnblogs.com/hany-postq473111315/p/13377190.html