Django系统开发(下)

简介: Django系统开发

Django系统开发(中):https://developer.aliyun.com/article/1427947


9.3 新建靓号


  • 列表点击跳转:/pretty/add
  • URL
  • ModelForm类
from django import forms
class PrettyModelForm(forms.ModelForm):


  • 函数
  • 实例化类的对象。
  • 通过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})
{% 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 %}


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
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


9.5 搜索手机号

# 索引方法1:
models.PrettyNum.objects.filter(mobile="19999999999",id=8)
# 索引方法2:(字典)
data_dict = {"mobile":"19999999999","id":8}
models.PrettyNum.objects.filter(**data_dict)
# 数字索引
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)
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)


9.6 分页

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


  • 分页的逻辑和处理规则
  • 封装分页类
  • 从头到尾开发
  • 写项目用公共组件
  • Bug,搜索+分页的情况下
分页时候,保留原来的搜索条件


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 %}


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()
{{ form.name }}     普通的Input框 无CSS样式
{{ form.password }}   普通的Input框 无CSS样式
  • 定义插件
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"})
        }
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"]
{{ form.name }}   BootStrap的Input框
{{ form.password }} BootStrap的Input框
  • 重新定义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
                }
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
                    }
  • 自定义类
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
                    }
# 继承BootStrapModelForm类中的功能
class UserEditModelForm(BootStrapModelForm):
    class Meta:
        model = models.UserInfo
        fields = ["name", "password"]


12.管理员操作


13.用户登录


cookie和session?

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

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


登录成功后:


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


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

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


目标:在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


  • 注册中间件,在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',
]
# 如果方法中没有返回值(返回None),继续向后走
# 如果有返回值 HttpResponse、render、redirect,则不在继续向后执行。


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')


  • 应用中间件
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',
]


13.3 注销


13.4 显示当前用户


14.图片验证码


14.1 生成图片

pip install pillow
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)


15.Ajax请求


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


  • GET
  • POST


特点:页面刷新


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


  • 依赖jQuery
  • 编写Ajax代码
$.ajax({
    url:"发送的地址", 
    type:"get",
    data:{
        n1:123,
        n2:456
    },
    // 提交成功后的返回值
    success:function(res){
        console.log(res);
    }
})


15.1 GET请求

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


def task_ajax(request):
    print(request.GET)
    return HttpResponse("成功了")


15.2 POST请求

$.ajax({
    url: '/task/ajax/',
    type: "get",
    data: {
        n1: 123,
        n2: 456
    },
    success: function (res) {
        console.log(res);
    }
})
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("成功了")


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 %}
目录
相关文章
|
3天前
|
BI Python
103-Django开发投票选举系统
这是一个基于 Python 3.11 和 Django 的全功能投票选举系统,提供用户认证、首页展示、投票功能、投票内容管理、数据统计与展示、用户管理和权限分配。系统支持第三方登录、搜索过滤、投票详情查看、选项选择及统计,并具有良好的扩展性和第三方系统集成能力。适用于各种选举场景,如学校选举、公司投票或在线调查。
8 0
|
3天前
|
前端开发 JavaScript 数据库
Django系统开发(中)
Django系统开发
45 0
|
3天前
|
关系型数据库 MySQL 数据库
Django系统开发(上)
Django系统开发
33 0
|
11月前
|
缓存 监控 安全
基于Django的电商项目的设计与实现
基于Django的电商项目的设计与实现
461 0
|
10月前
|
设计模式 前端开发 JavaScript
django搭建图书管理系统
django搭建图书管理系统
99 0
|
11月前
|
存储 前端开发 JavaScript
基于Django的学生信息管理系统的设计与实现
基于Django的学生信息管理系统的设计与实现
333 0
|
安全 关系型数据库 测试技术
Django 最佳实践
Django 最佳实践
124 0
|
SQL 数据库 开发者
Django启航(三)Django模型
Django启航(三)Django模型
131 0
|
关系型数据库 测试技术 数据库
django 项目需要注意的一些点
1.创建新项目    把静态文件夹的名字放在settings文件里面 STATIC_URL = '/static/' STATICFILES_DIRS=[ os.path.join(BASE_DIR,"static") ] 2.
1447 0
|
数据库 Python Shell
Django之路——2 Django的安装
Django的安装分为两种方式,一种是命令行安装,另外一种是pycharm安装。在这里只说一种在命令行里面安装的 1.命令行安装 这个自不必多说,直接上干货,如果遇到pip版本过低,安装失败的,请自自行按照命令行的提示更新pip版本。
1252 0