当前位置:   article > 正文

Django系统开发_django新建app

django新建app

Django系统开发

1.新建项目

  • 创建Django项目

在这里插入图片描述

  • 删除templates目录

  • 删除settings.py里templates -> DIRS的列表数据

在这里插入图片描述

2.创建app

  • 在Pycharm中

在这里插入图片描述

  • 注册app

在settings.py中找到 INSTALLED_APPS 加入对应路径 app01.apps.App01Config

在这里插入图片描述

3.表结构

from django.db import models

class Department(models.Model):
    """ 部门表 """
    title = models.CharField(verbose_name='标题', max_length=32)


class UserInfo(models.Model):
    """ 员工表 """
    name = models.CharField(verbose_name="姓名", max_length=16)
    password = models.CharField(verbose_name="密码", max_length=64)
    age = models.IntegerField(verbose_name="年龄")
    account = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
    create_time = models.DateTimeField(verbose_name="入职时间")

    # 无约束
    # depart_id = models.BigIntegerField(verbose_name="部门ID")
    # 1.有约束
    #   - to, 与那张表关联
    #   - to_field, 表中的那一列关联
    # 2.Django自动
    #   - 写的depart
    #   - 生成数据列 depart_id
    # 3.部门表被删除
    # 3.1 级联删除
    # depart = models.ForeignKey(to="Department", to_fields="id", on_delete=models.CASCADE())
    # 3.2 置空
    # depart = models.ForeignKey(to="Department", to_fields="id", null=True, blank=True, on_delete=models.SET_NULL)

    # 在jiango中做的约束
    gender_choices = (
        (1, "男"),
        (2, "女"),
    )
    gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

4.在MySQL中生成表

  • 工具连接MySQL生成数据库。
create database 数据库名字 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
  • 1
  • 修改配置文件,连接MySQL

    • 找到setting.py文件下的DATABASES

在这里插入图片描述

  • 写入配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'Django2',
        'USER': 'root',
        'PASSWORD': 'abc123.',
        'HOST': '127.0.0.1',
        'PORT': 3306
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
'
运行
  • Django命令生成数据表
python manage.py makemigrations
python manage.py migrate
  • 1
  • 2

在这里插入图片描述

  • 表结构创建成功

在这里插入图片描述

5.静态文件管理

在这里插入图片描述

6.部门管理

体验,原始方法做。

Django中提供Form和ModelForm组件(方便)

6.1部门列表

  • 框架设计

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YwzlMgn2-1678419303039)(D:\Typora_note\Django系统开发\image-20230203135413693.png)]

Step1:在urls.py中写入路径与函数对应关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vyMEGK8f-1678419303040)(D:\Typora_note\Django系统开发\image-20230203174738148.png)]

Step2:在views.py视图函数中写入路径对应的函数返回HTML文件

在这里插入图片描述

Step3:编写depart_list.html样式

在这里插入图片描述

Step4:在数据库中添加两条部门数据

insert into app01_department(title) values("IT部门"),("销售部");
  • 1

在这里插入图片描述

Step5:把MySQL数据插入depart.html

在这里插入图片描述

在这里插入图片描述

Step6:编写添加部门页面

增加一个跳转地址

在这里插入图片描述

编写页面

在这里插入图片描述

Step7:使新建部门写入数据库

1.在form中指定POST传参,并加入csrf_token使页面能正常跳转

在这里插入图片描述

2.在views.py中,写入获得数据,操作数据库,跳转页面内容

在这里插入图片描述

Step8:完善删除功能(与数据库关联

1.在views.py中,获取uid的值,操作数据库删除,跳转到部门列表

在这里插入图片描述

2.写入带删除参数的URL

在这里插入图片描述

Step8:完善编辑功能(关联数据库)

1.使用正则传参nid

在这里插入图片描述

2.获取nid,操作数据库更新,跳转到部门列表

在这里插入图片描述

3.展示页面传递默认值

在这里插入图片描述

7.模板的继承

  • 部门列表
  • 添加部门
  • 编辑部门

定义模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
    {% block css %}{% endblock %}
</head>
<body>
<h1>标题</h1>
<div>
    {% block content %}{% endblock %}
</div>
<h1>底部</h1>
<script src="{% static 'js/jquery-3.6.3.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
{% block js %}{% endblock %}
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

继承模板

{% extends 'test.html' %}

{% block css %}
	...
{% endblock %}


{% block content %}
    <h1>首页</h1>
{% endblock%}


{% block js %}
	...
{% endblock %}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

将部门列表,添加部门,编辑部门改造成继承模板

父模板(导航条,CSS,JS)

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .navbar {
            border-radius: 0;
        }
    </style>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
</head>
<body>
<nav class="navbar navbar-default">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">员工管理系统</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#">部门管理 <span class="sr-only">(current)</span></a></li>
                <li><a href="#">Link</a></li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
                <li><a href="#">登录</a></li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                       aria-expanded="false">姓名 <span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a href="#">Action</a></li>
                        <li><a href="#">Another action</a></li>
                        <li><a href="#">Something else here</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">Separated link</a></li>
                    </ul>
                </li>
            </ul>
        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>

{% block content %}{% endblock %}

<script src="{% static 'js/jquery-3.6.3.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

添加部门:

{% extends 'layout.html' %}

{% block content %}
<div>
    <div class="container">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h3 class="panel-title" href="/depart/add">新建部门</h3>
            </div>
            <div class="panel-body">
                <form method="post">
                    {% csrf_token %}
                    <div class="form-group">
                        <label>标题</label>
                        <input type="text" class="form-control" placeholder="请输入部门名称" name="title" />
                    </div>
                    <button type="submit" class="btn btn-primary">保 存</button>
                </form>
            </div>
        </div>
    </div>
</div>
{% endblock %}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

编辑部门:

{% extends 'layout.html' %}

{% block content %}
    <div>
        <div class="container">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title" href="/depart/add">编辑部门</h3>
                </div>
                <div class="panel-body">
                    <form method="post">
                        {% csrf_token %}
                        <div class="form-group">
                            <label>标题</label>
                            <input type="text" class="form-control" placeholder="请输入部门名称" name="title"
                                   value="{{ row_object.title }}"/>
                        </div>
                        <button type="submit" class="btn btn-primary">保 存</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
{% endblock %}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

部门列表:

{% extends 'layout.html' %}

{% block content %}
<div>
    <div class="container">
        <div style="margin-bottom: 10px">
            <a class="btn btn-success" href="/depart/add" >
                <span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
                新建部门
            </a>
        </div>
        <div class="panel panel-default">
            <!-- Default panel contents -->
            <div class="panel-heading">
                <span class="glyphicon glyphicon-th-list" aria-hidden="true"></span>
                部门列表
            </div>

            <!-- Table -->
            <table class="table table-bordered">
                <thead>
                <tr>
                    <th>ID</th>
                    <th>姓名</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody>
                {% for obj in queryset %}
                <tr>
                    <td>{{ obj.id }}</td>
                    <td>{{ obj.title }}</td>
                    <td>
                        <a class="btn-primary btn-xs" href="/depart/{{ obj.id }}/edit">编辑</a>
                        <a class="btn-danger btn-xs" href="/depart/delete?nid={{ obj.id }}">删除</a>
                    </td>
                </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</div>
{% endblock %}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

8.用户管理

插入数据:

insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id) values("刘备","666",23,100.68,"2023-01-01",1,1);
insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id) values("关羽","999",23,99.68,"2023-01-02",1,2);
insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id) values("张飞","333",23,98.68,"2023-01-03",1,2);
  • 1
  • 2
  • 3

在这里插入图片描述

在视图函数中获取数据库数据,传递给HTML

def user_list(request):
    queryset = models.UserInfo.objects.all()
    """
    for obj in queryset:
        print(obj.name, obj.password, obj.age, obj.account, obj.create_time.strftime("%Y-%m-%d"), obj.get_gender_display(), obj.depart.title)
    """
    return render(request, 'user_list.html', {"queryset": queryset})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
'
运行

新知识点 - 转换语法(在Python中的使用):

obj.create_time.strftime(“%Y-%m-%d”)

obj.get_gender_display()

obj.depart.title

在模板语法中循环展示数据

{% for obj in queryset %}
<tr>
    <td>{{ obj.id }}</td>
    <td>{{ obj.name }}</td>
    <td>{{ obj.password }}</td>
    <td>{{ obj.account }}</td>
    <td>{{ obj.create_time|date:"Y-m-d" }}</td>
    <td>{{ obj.get_gender_display }}</td>
    <td>{{ obj.depart.title }}</td>
    <td>
        <a class="btn-primary btn-xs">编辑</a>
        <a class="btn-danger btn-xs">删除</a>
    </td>
</tr>
{% endfor %}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

新知识点 - 转换语法(在模板语法中的使用):

obj.create_time|date:“Y-m-d”

get_gender_display

obj.depart.title

新建用户:

  • 原始方法

    - 用户提交数据没有校验。
    - 错误,页面上应有错误提示。
    - 页面上,每一个字段都需要重新写一遍。
    - 关联的数据,手动去获取并展示循环展示在页面
    
    • 1
    • 2
    • 3
    • 4
  • Django组件

    • Form组件(简便)
    • ModelForm组件(超级简便)

8.1 初识Form

1.views.py
class MyForm(Form):		# 定义一个类 在里面定义定义输入框,渲染到HTML中,则可以在HTML中调用成Input框
    user = forms.CharField(widget=forms.Input)
    pwd = forms.CharField(widget=forms.Input)
    email = forms.CharField(widget=forms.Input)
    account = forms.CharField(widget=forms.Input)
    create_time = forms.CharField(widget=forms.Input)
    depart = forms.CharField(widget=forms.Input)
    gender = forms.CharField(widget=forms.Input)

def user_add(request):
    if request.method == "GET":
        form = MyForm()
        return render(request, 'user_add.html', context, {"form":form})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
2.user_add.html

一个个生成Input框

<form method="post">
    {{ form.user }}		<!-- 通过渲染传入的form,使用模板语法,生成Input框 -->
    {{ form.pwd }}
    {{ form.email }}
    <!-- <input type="text" class="form-control" placeholder="姓名" name="user"/> -->
</form>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

循环生成Input框

<form method="post">
    {% for field in form %}		<!-- 通过渲染传入的form,使用模板语法,循环生成Input框 -->
    	{{ field }}
    {% endfor %}
    <!-- <input type="text" class="form-control" placeholder="姓名" name="user"/> -->
</form>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

8.2 ModelForm

models.py

class UserInfo(models.Model):
    name = models.CharField(verbose_name="姓名", max_length=16)
    password = models.CharField(verbose_name="密码", max_length=64)
    age = models.IntegerField(verbose_name="年龄")
    account = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
    create_time = models.DateTimeField(verbose_name="入职时间")
    depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)

    gender_choices = (
        (1, "男"),
        (2, "女"),
    )
    gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

views.py

class MyForm(Form):
    xx = forms.CharField()		# 可自定义字段
    class Meta:
        model = UserInfo		# 实例化UserInfo对象iang
        fields = ["name","password","age","xx"]	# 可获取UserInfo中的字段

def user_add(request):
    if request.method == "GET":
        form = MyForm()
        return render(request, 'user_add.html', context, {"form":form})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 部门管理

  • 用户管理

    • 用户列表
    • 新建用户
    - ModelForm,针对数据库中的某个表。
    - Form
    
    • 1
    • 2

8.3 编辑用户

  • 点击编辑,跳转到编辑页面(将编辑行的ID携带过去)
  • 编辑页面(存放默认数据,根据ID获取并设置到页面中)
  • 提交:
    • 错误提示
    • 数据校验
    • 在数据库更新

9.靓号管理

9.1 表结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5IKqLMxI-1678419303056)(D:\Typora_note\Djiango系统开发\image-20230205220244573.png)]

根据表结构的需求,在models.py中创建类(由类生成数据库中的表)

class PrettyNum(models.Model):
    mobile = models.CharField(verbose_name="手机号", max_length=11)
    price = models.IntegerField(verbose_name="价格", default=0)
    level_choices = (
        (1, "1级"),
        (2, "2级"),
        (3, "3级"),
        (4, "4级"),
        (5, "5级"),
    )
    level = models.SmallIntegerField(verbose_name="级别", choices=level_choices, default=1)
    status_choices = (
        (1, "已占用"),
        (2, "为占用"),
    )
    status = models.SmallIntegerField(verbose_name="状态", choices=status_choices, default=2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

模拟创建一些数据:

insert into app01_prettynum(mobile,price,level,status) values("12345678911",10,1,1);
  • 1
mysql> select * from app01_prettynum;
+----+-------------+-------+-------+--------+
| id | mobile      | price | level | status |
+----+-------------+-------+-------+--------+
|  1 | 12345678911 |    10 |     1 |      1 |
|  2 | 12345678911 |    10 |     1 |      1 |
|  3 | 12345678911 |    10 |     1 |      1 |
+----+-------------+-------+-------+--------+
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

9.2 靓号列表

  • URL

  • 函数

    • 获取所有的靓号
    • 结合html+render将靓号罗列出来
    id	手机号	价格	级别(中文)	状态(中文)
    
    • 1
def pretty_list(request):
    """ 靓号列表 """
    queryset = models.PrettyNum.objects.all().order_by("-id")
    return render(request, 'pretty_list.html', {"queryset": queryset})
  • 1
  • 2
  • 3
  • 4
'
运行
{% extends 'layout.html' %}

{% block content %}
    <div>
        <div class="container">
            <div style="margin-bottom: 10px">
                <a class="btn btn-success" href="/pretty/add">
                    <span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
                    添加靓号
                </a>
            </div>
            <div class="panel panel-default">
                <!-- Default panel contents -->
                <div class="panel-heading">
                    <span class="glyphicon glyphicon-th-list" aria-hidden="true"></span>
                    靓号列表
                </div>

                <!-- Table -->
                <table class="table table-bordered">
                    <thead>
                    <tr>
                        <th>ID</th>
                        <th>手机号</th>
                        <th>价格</th>
                        <th>级别</th>
                        <th>状态</th>
                        <th>操作</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for obj in queryset %}
                        <tr>
                            <td>{{ obj.id }}</td>
                            <td>{{ obj.mobile }}</td>
                            <td>{{ obj.price }}</td>
                            <td>{{ obj.get_level_display }}</td>
                            <td>{{ obj.get_status_display }}</td>
                            <td>
                                <a class="btn-primary btn-xs" href="/user/{{ obj.id }}/edit">编辑</a>
                                <a class="btn-danger btn-xs" href="/user/{{ obj.id }}/delete">删除</a>
                            </td>
                        </tr>
                    {% endfor %}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
{% endblock %}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

9.3 新建靓号

  • 列表点击跳转:/pretty/add

  • URL

  • ModelForm类

    from django import forms
    
    class PrettyModelForm(forms.ModelForm):
    	
    
    • 1
    • 2
    • 3
    • 4
  • 函数

    • 实例化类的对象。
    • 通过render将对象传入到HTML中。
    • 模板的循环展示所有的字段。
def pretty_add(request):
    """ 添加靓号 """
    if request.method == "GET":
        form = PrettyModelForm()
        return render(request, 'pretty_add.html', {"form": form})
    form = PrettyModelForm(data=request.POST)
    if form.is_valid():
        form.save()
        return redirect('/pretty/list')
    else:
        return render(request, "pretty_add.html", {"form": form})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
'
运行
{% extends 'layout.html' %}

{% block content %}
    <div>
        <div class="container">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title" href="/depart/add">添加靓号</h3>
                </div>
                <div class="panel-body">
                    <form method="post" novalidate>  <!-- novalidate关闭浏览器校验 -->
                        {% csrf_token %}
                        {% for field in form %}
                            <div class="form-group">
                                <label>{{ field.label }}</label>
                                {{ field }}
                                <span style="color: red">{{ field.errors.0 }}</span>
                            </div>
                        {% endfor %}
                        <button type="submit" class="btn btn-primary">保 存</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
{% endblock %}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

9.4 编辑靓号

  • 列表页面:/pretty/数字/edit
  • URL
  • 函数
    • 根据ID获取当前编辑的对象
    • ModelForm配合
    • 提交修改

不允许手机号重复

  • 添加:【正则表达式】【手机号不能存在】
queryset = models.PrettyNum.objects.filter(mobile="18888888888")

obj = models.PrettyNum.objects.filter(mobile="18888888888").first()

exists = models.PrettyNum.objects.filter(mobile="18888888888").exis
  • 1
  • 2
  • 3
  • 4
  • 5
def clean_mobile(self):
txt_mobile = self.cleaned_data["mobile"]
exists = models.PrettyNum.objects.exclude(id=self.instance.pk).filter(mobile=txt_mobile).exists()
if exists:
    raise ValidationError("手机号已存在")
# 验证通过,用户输入的值返回
return txt_mobile
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

9.5 搜索手机号

# 索引方法1:
models.PrettyNum.objects.filter(mobile="19999999999",id=8)

# 索引方法2:(字典)
data_dict = {"mobile":"19999999999","id":8}
models.PrettyNum.objects.filter(**data_dict)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
# 数字索引
models.PrettyNum.objects.filter(id=12)			# 等于12
models.PrettyNum.objects.filter(id__gt=12)		# 大于12
models.PrettyNum.objects.filter(id__gte=12)		# 大于等于12
models.PrettyNum.objects.filter(id__lt=12)		# 小于12
models.PrettyNum.objects.filter(id__lte=12)		# 小于等于12

data_dict = {"id__lte":12}
models.PrettyNum.objects.filter(**data_dict)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
models.PrettyNum.objects.filter(mobile="999")				# 等于
models.PrettyNum.objects.filter(mobile__startswith="199")	# 筛选出以199开头
models.PrettyNum.objects.filter(mobile__endswith="999")		# 筛选出以999结尾
models.PrettyNum.objects.filter(mobile__contains="999")		# 筛选出包含999

data_dict = {"mobile__contains":"999"}
models.PrettyNum.objects.filter(**data_dict)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

9.6 分页

queryset = models.PrettyNum.objects.all()

queryset = models.PrettyNum.objects.filter(id=1)[0:10]

queryset = models.PrettyNum.objects.all()[0:1]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 分页的逻辑和处理规则

  • 封装分页类

    • 从头到尾开发
    • 写项目用公共组件
  • Bug,搜索+分页的情况下

    分页时候,保留原来的搜索条件
    
    • 1

10.时间插件

<!-- 引入CSS和JS 给时间框添加id -->
{% block css %}
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-datepicker-master/dist/css/bootstrap-datepicker.min.css' %}">
{% endblock %}

{% block js %}
    <script src="{% static 'plugins/bootstrap-datepicker-master/js/bootstrap-datepicker.js' %}"></script>
    <script src="{% static 'plugins/bootstrap-datepicker-master/dist/locales/bootstrap-datepicker.zh-CN.min.js' %}"></script>
    <script>
        $(function () {
            $('#id_create_time').datepicker({
                format: 'yyyy-mm-dd',
                startDate: '0',
                languag: "zh-CN",
                autoclose: true
            });
        })
    </script>
{% endblock %}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

11.ModelForm和BootScript

  • ModelForm可以帮助我们生成HTML标签
# 定义UserModelForm类用于生成Input框
class UserModelForm(forms.ModelForm):
    name = forms.CharField(min_length=3, label="用户名")
    class Meta:
        model = models.UserInfo
        fields = ["name", "password"]

form = UserModelForm()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
{{ form.name }}			普通的Input框 无CSS样式
{{ form.password }}		普通的Input框 无CSS样式
  • 1
  • 2
  • 定义插件
class UserModelForm(forms.ModelForm):
    class Meta:
        model = models.UserInfo
        fields = ["name", "password", "age", "account", "create_time", "gender", "depart"]
        widgets = {
             "name": forms.TextInput(attrs={"class": "form-control"})
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
class UserModelForm(forms.ModelForm):
    name = forms.CharField(
    	min_length=3,
        label="用户名",
        widget=forms.TextInput(attrs={"class": "form-control"})
    )
    class Meta:
        model = models.UserInfo
        fields = ["name", "password", "age", "account", "create_time", "gender", "depart"]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
{{ form.name }}		BootStrap的Input框
{{ form.password }}	BootStrap的Input框
  • 1
  • 2
  • 重新定义init方法,批量设置
class UserModelForm(forms.ModelForm):
    class Meta:
        model = models.UserInfo
        fields = ["name", "password"]
        
    def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            # 循环找到所有的插件,添加了class="form-control"
            for name, field in self.fields.items():
                field.widget.attrs = {
                    "class": "form-control",
                    "placeholder": field.label
                }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
class UserModelForm(forms.ModelForm):
    class Meta:
        model = models.UserInfo
        fields = ["name", "password"]
        
    def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            # 循环找到所有的插件,添加了class="form-control"
            for name, field in self.fields.items():
                # 字段中若有属性,保留原来的属性,若没有属性,则增加
                if field.widget.attrs:
                    field.widget.attrs["class"] = "form-control"
                    field.widget.attrs["placeholder"] = field.label
                else:
                    field.widget.attrs = {
                        "class": "form-control",
                        "placeholder": field.label
                    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 自定义类
class BootStrapModelForm(forms.ModelForm):        
    def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            # 循环找到所有的插件,添加了class="form-control"
            for name, field in self.fields.items():
                # 字段中若有属性,保留原来的属性,若没有属性,则增加
                if field.widget.attrs:
                    field.widget.attrs["class"] = "form-control"
                    field.widget.attrs["placeholder"] = field.label
                else:
                    field.widget.attrs = {
                        "class": "form-control",
                        "placeholder": field.label
                    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
# 继承BootStrapModelForm类中的功能
class UserEditModelForm(BootStrapModelForm):
    class Meta:
        model = models.UserInfo
        fields = ["name", "password"]
  • 1
  • 2
  • 3
  • 4
  • 5

12.管理员操作

在这里插入图片描述

13.用户登录

cookie和session?

cookie用于存放用户认证信息 如k1=sfsagglfskfsdfasdf

session是一个概念 用于存储用户的配置信息

登录成功后:

  • cookie,随机字符串
  • session,用户信息

在其他需要登录才能访问的页面中,都需要加入:

info = request.session.get("info")
if not info:
    return redirect('/login')
  • 1
  • 2
  • 3

目标:在18个视图函数前面统一加入判断

13.1 中间件

  • 定义中间件
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse

class M1(MiddlewareMixin):
    """ 中间件1 """

    def process_request(self, request):
        print("M1.进来了")
        return HttpResponse("无权访问")

    def process_response(self, request, response):
        print("M1.走了")
        return response
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 注册中间件,在settings中
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'app01.middleware.auth.M1',
    'app01.middleware.auth.M2',
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
'
运行
# 如果方法中没有返回值(返回None),继续向后走
# 如果有返回值 HttpResponse、render、redirect,则不在继续向后执行。
  • 1
  • 2
'
运行

13.2 中间件实现登录校验

  • 编写中间件
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse, redirect

class AuthMiddleware(MiddlewareMixin):
    """ 中间件1 """

    def process_request(self, request):
        if request.path_info == "/login/":
            return

        info_dict = request.session.get("info")
        if info_dict:
            return
        return redirect('/login')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 应用中间件
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'app01.middleware.auth.AuthMiddleware',
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
'
运行

13.3 注销

在这里插入图片描述

13.4 显示当前用户

在这里插入图片描述

14.图片验证码

在这里插入图片描述

14.1 生成图片

pip install pillow
  • 1
import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter


def check_code(width=120, height=30, char_length=5, font_file='kumo.ttf', font_size=28):
    code = []
    img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255))
    draw = ImageDraw.Draw(img, mode='RGB')

    def rndChar():
        """
        生成随机字母
        :return:
        """
        return chr(random.randint(65, 90))

    def rndColor():
        """
        生成随机颜色
        :return:
        """
        return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255))

    # 写文字
    font = ImageFont.truetype(font_file, font_size)
    for i in range(char_length):
        char = rndChar()
        code.append(char)
        h = random.randint(0, 4)
        draw.text([i * width / char_length, h], char, font=font, fill=rndColor())

    # 写干扰点
    for i in range(40):
        draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())

    # 写干扰圆圈
    for i in range(40):
        draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
        x = random.randint(0, width)
        y = random.randint(0, height)
        draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor())

    # 画干扰线
    for i in range(5):
        x1 = random.randint(0, width)
        y1 = random.randint(0, height)
        x2 = random.randint(0, width)
        y2 = random.randint(0, height)

        draw.line((x1, y1, x2, y2), fill=rndColor())

    img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
    return img, ''.join(code)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
'
运行

15.Ajax请求

浏览器向网站发送请求时:URL和表单的形式提交。

  • GET
  • POST

特点:页面刷新

除此之外,也可以基于Ajax向后台发送请求(隐蔽的)

  • 依赖jQuery
  • 编写Ajax代码
$.ajax({
    url:"发送的地址", 
    type:"get",
    data:{
        n1:123,
        n2:456
    },
    // 提交成功后的返回值
    success:function(res){
        console.log(res);
    }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

15.1 GET请求

$.ajax({
    url: '/task/ajax/',
    type: "get",
    data: {
        n1: 123,
        n2: 456
    },
    success: function (res) {
        console.log(res);
    }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
def task_ajax(request):
    print(request.GET)
    return HttpResponse("成功了")
  • 1
  • 2
  • 3
'
运行

15.2 POST请求

$.ajax({
    url: '/task/ajax/',
    type: "get",
    data: {
        n1: 123,
        n2: 456
    },
    success: function (res) {
        console.log(res);
    }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
from django.shortcuts import render, HttpResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def task_ajax(request):
    print(request.GET)
    return HttpResponse("成功了")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

15.3 关闭绑定事件

{% extends 'layout.html' %}

{% block content %}
    <div class="container">
        <h1>任务管理</h1>

        <h3>示例1</h3>
        <input id="btn1" type="button" class="btn btn-primary" value="点击" onclick="clickMe();"/>
    </div>
{% endblock %}

{% block js %}
    <script type="text/javascript">
        $(function () {
            // 页面框架加载完成之后代码自动执行
            bindBtn1Event();
        })

        function bindBtn1Event() {
            $("#btn1").click(function () {
                $.ajax({
                    url: '/task/ajax/',
                    type: "get",
                    data: {
                        n1: 123,
                        n2: 456
                    },
                    success: function (res) {
                        console.log(res);
                    }
                })
            })
        }

    </script>
{% endblock %}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

计算机编程交流群:940878539 欢迎加入Q群

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/865202
推荐阅读
相关标签
  

闽ICP备14008679号