前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Django Web开发基础知识

Django Web开发基础知识

作者头像
微软技术分享
发布2022-12-28 16:33:44
2.1K0
发布2022-12-28 16:33:44

本文章只是学习笔记,部分资料参考自互联网,图片非原创,仅用于学习理解 !

MVC 与 MTV

MVC - Model View Controller,模型(model)-视图(view)-控制器(controller)的缩写,是软件工程中的一种软件架构模式,Model模型中主要用于存储与数据库相关的字段或数据库通信方面的东西,Controller控制器用于存储URL的分发等,最后的View视图则是完善控制器中的路径分发,每一个路径对应一个view视图函数。

模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的、松耦合的方式连接在一起:

A.模型负责业务对象与数据库的映射(ORM) B.视图负责与用户的交互(页面) C.控制器接受用户的输入调用模型和视图完成用户的请求

ORM:对象关系映射(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping)

通常情况下我们写代码用的是面向对象的方法,而我们的数据库无法支持面向对象的编程,为了解决两者之间的不同,就出现了ORM映射技术,使用这种技术我们无需关注sql语句的具体编写,只需要使用特定的API即可完成复杂的查询删除等任务,但有一个缺点,采用此技术在一定程度上会消耗系统部分资源,而对于非常复杂的查询工作,还是要使用纯SQL语句来写。

Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django的MTV分别是值:

M 代表模型(Model): 负责业务对象和数据库的关系映射(ORM)。 T 代表模板 (Template):负责如何把页面展示给用户(html)。 V 代表视图(View): 负责业务逻辑,并在适当时候调用Model和Template。

除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template,MTV的响应模式如下所示:

这种设计模式优势在于各组件都是松耦合的。每个由Django驱动的Web应用都有着明确的目的,并且可独立更改而不影响到其它的部分。

HTTP协议:Hyper Text Transfer Protocol(超文本传输协议),是用于万维网服务器与本地浏览器之间传输超文本的传送协议。

该协议是基于TCP/IP的请求协议

HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并 返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有 接收到请求之前不会发送响应无状态保存

HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议自身不对请求和响应之间的通信状态进行保存,协议对于发送过的请求或响应都不做持久化处理。

无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

HTTP请求方式

GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,POST方法是把提交的数据放在HTTP包的Body中. GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制. GET与POST请求在服务端获取请求数据方式不同。 GET方式提交数据,会带来安全问题,而POST请求则相对安全。

创建第一个django项目

1.如果是使用Pycharm创建的项目,直接创建项目,即可。

2.如果没有创建app的名字,也可以在进入django目录中,执行 python manage.py startapp MyWeb 命令创建.

更多django shell命令行参数。

代码语言:javascript
复制
python manage.py shell     #进入django shell
python manage.py dbshell   #进入django dbshell
python manage.py check     #检查django项目完整性
python manage.py flush     #清空数据库
python manage.py compilemessages   #编译语言文件
python manage.py makemessages      #创建语言文件
python manage.py showmigrations    #查看生成的数据库同步脚本
python manage.py sqlflush          #查看生成清空数据库的脚本
python manage.py sqlmigrate        #查看数据库同步的sql语句
python manage.py dumpdata          #导出数据
python manage.py loaddata          #导入数据
python manage.py diffsettings      #查看你的配置和django默认配置的不同之处

2.修改settings.py 配置文件,导入我们的app的名字,去掉csrf这个选项

代码语言:javascript
复制
MIDDLEWARE = [
'django.middleware.csrf.CsrfViewMiddleware',  # 为了能够开心玩耍,把这个干掉
]

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'MyWeb.apps.MywebConfig'           # 导入
]

3.来urls.py里面写一条路由,名字就叫hello , 映射到views.hello函数下处理此请求。

代码语言:javascript
复制
from MyWeb import views       # 导入

urlpatterns = [
    path('admin/', admin.site.urls),
    path('hello/',views.hello)
]

4.最后在myweb里面的views.py设置一个视图函数,最后运行。

代码语言:javascript
复制
from django.shortcuts import HttpResponse

# Create your views here.
# 这个request必须加,不然会报错
def hello(request):
    return HttpResponse("<h1>hello lyshark</h1>")

5.配置好以后,启动django,访问 http://127.0.0.1:8000/ 完成了。

6.如果需要引入静态资源,需要设置一下settings.py

代码语言:javascript
复制
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/

# 这个路径是对应 src="/static/ 的别名
# 如果这个路径改为 STATIC_URL = '/abc/' 那么<script src="/abc/xxx.js"></script>
STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR,'static'),
)

Django 初始化操作

初始化Django:

代码语言:javascript
复制
D:\> pip install django                              # 安装
D:\> django-admin startproject MyProject             # 创建项目
D:\MyProject> django-admin startapp MyWeb            # 创建APP
D:\MyProject> python manage.py runserver 0.0.0.0:80  # 启动Django

D:\MyProject> python manage.py shell   # 进入Django交互shell
D:\MyProject> python manage.py dbshell # 进入DBShell
D:\MyProject> python manage.py check   # 检查Django完整性

修改一下django的配置文件settings.py,导入我们生成APP的名字.

代码语言:javascript
复制
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware',                # 注释掉此行
    'django.contrib.auth.middleware.AuthenticationMiddleware',
]
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'MyWeb.apps.MywebConfig'           # 添加此行,导入我们的APP的名字
]

然会修改urls.py在这里写一条路由记录.

代码语言:javascript
复制
from MyWeb import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path("hello/",views.hello,name="hello")
]

最后我们在views.py视图函数里添加一条路由.

代码语言:javascript
复制
from django.shortcuts import HttpResponse

def hello(request):
    return HttpResponse("<h1>hello lyshark</h1>")

有时候我们需要在本地引入JS或者静态资源,此时你需要修改一下Django的setting.py里面的路径.

代码语言:javascript
复制
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
# 此时我们的默认路径是/static/,那么前端就可以直接调用<script src="/static/lyshark.js">
STATIC_URL = '/static/'
STATICFILES_DIRS=(
    os.path.join(BASE_DIR,'static')
)

Django 模板与视图

简单的路由编写:

代码语言:javascript
复制
urlpatterns = [
    path('admin/', admin.site.urls),
    path('',views.index,name="index"),                                     # 一条访问主站的路由
    path('login/id=<int:id>&name=<str:name>',views.login,name="login"),    # 名称后面传递参数
    path('add/<int:x>/<int:y>/',views.add,name="add")                      # 路径中传递参数
]

from django.shortcuts import render,HttpResponse
def index(request):
    return render(request,"index.html")

def login(request, id, name):
    return HttpResponse("用户ID{} , 用户名{} ".format(id,name))

def add(request,x,y):
    temp = int(x)+int(y)
    return HttpResponse("相加结果:{}".format(temp))

使用模板传递简单的参数:

代码语言:javascript
复制
**用户名: {{ user }} 密码:{{ pasd }} 标题:{{ title }}:**

def index(request):
    username = "lyshark"
    password = "123123"
    title = "hello lyshark"
    return render(request,"index.html",{"user":username,"pasd":password,"title":title})

后端组装数据然后传递给前端:

代码语言:javascript
复制
**用户名: {{ user }} 密码:{{ pasd }} 标题:{{ title }}:**

def index(request):
    username = "admin"
    password = "123123"
    title = "hello lyshark"

    dict = {
        "user": username,
        "pasd": password,
        "title": title
    }
    return render(request,"index.html",dict)

通过info变量遍历出指定字段元素:

代码语言:javascript
复制
**站点名称:{{ info.site }} 站点描述:{{ info.content }}:**

def index(request):
    info = {"site":"blib.cn","content":"hello lyshark"}
    return render(request,"index.html",{"info":info})

通过for语句遍历打印列表数据:

代码语言:javascript
复制
    {% for item in total %}
        **打印数据: {{ item }}:**<br>
    {% endfor %}

def index(request):
    lists = ["HTML","CSS","JAVASCRIPT","Python","JQuery"]
    return render(request,"index.html",{"total":lists})

通过for语句倒序循环打印:

代码语言:javascript
复制
    {% for item in total reversed%}
        **打印数据: {{ item }}:**<br>
    {% endfor %}

def index(request):
    lists = ["1","2","3","4","5"]
    return render(request,"index.html",{"total":lists})

通过使用for循环遍历字典:

代码语言:javascript
复制
{% for key,value in info.items %}
    {{ key }} : {{ value }}
{% endfor %}

def index(request):
    info = {"site":"blib.cn","content":"hello lyshark"}
    info1 = {"site": "blib.cn", "content": "hello admin"}

    return render(request,"index.html",{"info":info,"info1":info1})

简单的路径拼接:

代码语言:javascript
复制
<a href="{{ request.path }}?uid=1">当前网址加参数</a>

<!--获取当前路径      拼接成 /add/4/5-->
{{ request.path }}{% url 'add' 4 5 %}

def add(request,x,y):
    temp = int(x)+int(y)
    return HttpResponse("相加结果:{}".format(temp))

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

判断用户是否登录:

代码语言:javascript
复制
{% if request.user.is_authenticated %}
    {{ request.user.username }},您好!
{% else %}
    请登陆,这里放登陆链接
{% endif %}

使用if语句判断数据:

代码语言:javascript
复制
{% if username == "lyshark" and password == "123123" %}
    **恭喜你:**
{% elif username == "admin" or password == "123123" %}
    **欢迎管理员:**
{% else %}
    **这个都不是:**
{% endif %}

def index(request):
    username = "admin"
    password = "123123"
    return render(request,"index.html",{"username":username,"password":password})

if语句也可以判断列表元素:

代码语言:javascript
复制
{% if 1 in list %}
    **在里面:**
{% elif 10 not in list %}
    ** 不在里面:**
{% endif %}

def index(request):
    list = [1,2,3,4,5]
    return render(request,"index.html",{"list":list})

最后的大总结:if与for语句的结合:

代码语言:javascript
复制
{% for item in info %}
    {% if forloop.first %}
        **开始了:**
    {% endif %}
    {{ forloop.counter }} : {{ item }}<br>
    {% if forloop.last %}
        **最后了:**
    {% endif %}
{% endfor %}

def index(request):
    list = map(str,range(100))
    return render(request,"index.html",{"info":list})

forloop.counter 索引从 1 开始算
forloop.counter0    索引从 0 开始算
forloop.revcounter  索引从最大长度到 1
forloop.revcounter0 索引从最大长度到 0
forloop.first   当遍历的元素为第一项时为真
forloop.last    当遍历的元素为最后一项时为真
forloop.parentloop  
用在嵌套的 for 循环中,获取上一层 for 循环的 forloop

常用的过滤器:: 常用的过滤器,有以下几种.

代码语言:javascript
复制
    ** 列表长度: {{ total | length }}:**<br>
    ** 输出大小: {{ size | filesizeformat }}:**<br>
    ** 输出时间: {{ date | date:"Y-m-d" }}:**<br>
    ** 首字母大写: {{ title | capfirst }}:**<br>
    ** 从字符串中移除hello字符: {{title | cut:"hello" }}:**<br>
    ** 显示字符串第一个元素: {{ total | first }}:**<br>
    ** 显示字符串最后一个元素: {{ total | last }}:**<br>
    ** 大小写转换(upper/lower): {{ title | upper }}:**<br>
    ** 对数据切片: {{ title | slice:"2:-1" }}:**<br>
    **截断字符:{{ title | truncatechars:5 }}:**<br>
    **截断单词:{{ title | truncatewords:1 }}:**

def index(request):
    filesize = 10240
    title = "hello lyshark"
    date = datetime.datetime.now()
    lists = ["1","2","3","4","5"]
    return render(request,"index.html",{"total":lists,"size":filesize,"date":date,"title":title})

自定义过滤器与标签:

1.首先在Django项目下的APP里面,创建一个templatetags的目录,这个目录名不能变.

代码语言:javascript
复制
MyWeb/
    __init__.py
    models.py
    templatetags/
        __init__.py
        mysimple.py
    views.py

2.在templatetags目录下创建任意的py文件,此处我们就创建一个mysimple.py,并写入以下两条内容.

代码语言:javascript
复制
from django import template
from django.utils.safestring import mark_safe

register = template.Library() # 此处必须这样写

# simple_tag(自定义标签):不会限制传参,但不支持if
@register.simple_tag
def simple_time(var1,var2,var3):
    temp = int(var1)+int(var2)+int(var3)
    return temp

# filter(自定义过滤器):限制传参2个,但支持if
@register.filter
def My_filter(value, arg):
    # 传递一个参数的过滤器
    return str.upper(value) + arg

3.在我们需要使用自定义过滤器的时候,必须在index.html中引入这个变量,然后在前端就可以调用了.

代码语言:javascript
复制
# name: views.py
def index(request):
    title = "hello"
    return render(request,"index.html",{"title":title})

# name: index.html
<!--引入自定义的过滤器-->
{% load mysimple %}

**自定义标签返回数值: {% simple_time 10 20 30 %}:**          <!-- 传递多个参数 -->
**传递一个参数的过滤器: {{ title | My_filter:'lyshark' }}:** <!-- 传递一个参数 -->

模板与模板继承:

代码语言:javascript
复制
母板:             {% block title %}{% endblock %}
子板继承:         {% extends "base.html" %}
子板中使用其他模板: {% include "xx.html" %}
设置标题:          {% block title %}{% endblock %}
使用CSS资源:       {% block css %} {% endblock %}
使用JS资源:        {% block js %} {% endblock %}

1.首先创建一个base.html文件,以作为我们的母版.

代码语言:javascript
复制
<html>
<head>
    <meta charset="UTF-8">
    {% block css %}{% endblock %}
</head>
    <body>
        <div class="pg-body">
            <div class="body-menu">
                <ul>
                    <li><a href="/user">用户管理</a></li>
                    <li><a href="/hosts">资产管理</a></li>
                </ul>
            </div>
            <div class="body-content">
                {% block body %}{% endblock %}   <!--占位符,用于填充子版块-->
            </div>
        </div>
        {% block js %}{% endblock %}
    </body>
</html>

接着我们需要创建一个子板并继承母版,此处我们创建一个hosts.html这样的文件.

代码语言:javascript
复制
{% extends 'base.html' %}
{% block js %} {% endblock %}
{% block css %} {% endblock %}

{% block body %}
    <table>
        {% for item in host %}
            <tr>
                <td>{{ item.hostname }}</td>
                <td>{{ item.port }}</td>
            </tr>
        {% endfor %}
    </table>
{% endblock %}

我们继续创建一个user.html,同样也是继承base.html模板.

代码语言:javascript
复制
{% extends 'base.html' %}

{% block js %} {% endblock %}
{% block css %} {% endblock %}

{% block body %}
    <ul>
    {% for item in user_list %}
        <li>{{ item.username }},{{ item.salary }}</li>
    {% endfor %}
    </ul>
{% endblock %}

此处我们需要在urls.py里面写好路由分发.

代码语言:javascript
复制
from django.contrib import admin
from django.urls import path
from MyWeb import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',views.index,name="index"),
    path('hosts/',views.hosts,name="hosts"),
    path('user/',views.userinfo,name="user")
]

然后写好views.py中的视图函数,默认我们返回base.html这个页面.

代码语言:javascript
复制
from django.shortcuts import render
from django.shortcuts import HttpResponse

def index(request):
    return render(request,"base.html")

def hosts(request):
    hosts_list = []
    for i in range(10):
        temp = {'hostname':'192.168.1.'+str(i),'port':80}
        hosts_list.append(temp)
    return render(request,'hosts.html',{'host':hosts_list})

def userinfo(request):
    user_list = []
    for i in range(10):
        temp = {'username': 'user' + str(i),'salary':80}
        user_list.append(temp)
    return render(request,'user.html',{'user_list':user_list})

简单的用户登录:

代码语言:javascript
复制
# name:login.html
<!DOCTYPE html>
<body lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
    <form action="{% url 'login' %}" method="post">  # 通过模板获取到login的试图
        <input type="text" name="username" />
        <input type="text" name="password" />
        <input type="submit" name="提交"/>
    </form>
</body>
</html>

# name: urls.py
from django.contrib import admin
from django.urls import path
from MyWeb import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', views.login, name="login")  # name是给视图起一个名字
]

# name:views.py
from django.shortcuts import render,HttpResponse

def login(request):
    if request.method == "GET":
        return render(request,"index.html")
    elif request.method == "POST":
        username = request.POST.get("username")
        password = request.POST.get("password")
        return HttpResponse("您提交的用户:{} 密码:{}".format(username,password))

Django 表单操作

普通Form表单的提交:

代码语言:javascript
复制
<!-- name:index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/" method="post">
        <p>账号:<input type="text" name="username"><span>{{ error.username }}</span></p>
        <p>密码:<input type="password" name="password"><span>{{ error.password }}</span></p>
        <input type="submit" value="提交请求">
    </form>
</body>
</html>
代码语言:javascript
复制
# name: views.py
from django.shortcuts import render,HttpResponse

def index(request):
    if request.method == "GET":
        return render(request,"index.html")
    else:
        username = request.POST.get("username")
        password = request.POST.get("password")
        error = {"username":"","password":""}
        if len(username) > 10:
            error["username"]="用户名不能大于10"
        if len(password) < 5:
            error["password"] = "密码不能小于5"
        return render(request,"index.html",{"error":error})

实现单项选择框:

代码语言:javascript
复制
<form action="/index/" method="post">

    选择A:

    <select name="tag_select_a">

        {% for item in total_a %}

            <option value = "{{ item }}"> {{ item }} </option>

        {% endfor %}
    </select>
    选择B:
    <select name="tag_select_b">
        {% for item in total_b %}
            <option value = "{{ item }}"> {{ item }} </option>
        {% endfor %}
    </select>
    <input type="submit" value="提交选择">
</form>
代码语言:javascript
复制
def index(request):
    if request.method == "GET":
        tag_select_a = ["HTML", "CSS", "JAVASCRIPT", "Python", "JQuery"]
        tag_select_b = ["MySQL","Oracle","MSSQL"]
        return render(request, "index.html", {"total_a": tag_select_a,"total_b": tag_select_b})
    elif request.method == "POST":
        select_a = request.POST.get("tag_select_a")
        select_b = request.POST.get("tag_select_b")
        return HttpResponse("选择A: {} 选择B: {}".format(select_a,select_b))<b>普通Form表单的提交</b>

提交账号密码:

代码语言:javascript
复制
<!-- name:index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/" method="post">
        <p>账号:<input type="text" name="username"><span>{{ error.username }}</span></p>
        <p>密码:<input type="password" name="password"><span>{{ error.password }}</span></p>
        <input type="submit" value="提交请求">
    </form>
</body>
</html>
代码语言:javascript
复制
# name: views.py
from django.shortcuts import render,HttpResponse

def index(request):
    if request.method == "GET":
        return render(request,"index.html")
    else:
        username = request.POST.get("username")
        password = request.POST.get("password")
        error = {"username":"","password":""}
        if len(username) > 10:
            error["username"]="用户名不能大于10"
        if len(password) < 5:
            error["password"] = "密码不能小于5"
        return render(request,"index.html",{"error":error})

Form实现登录表单:

代码语言:javascript
复制
<!--name:index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/" method="post" novalidate>
        <p>账号: {{ form.username }} {{ form.username.errors.0 }}</p>
        <p>密码: {{ form.password }} {{ form.errors.password }}</p>
        <p>重复: {{ form.RepeatPass }} {{ form.errors.RepeatPass }}</p>
        <input type="submit" value="提交">
    </form>
</body>
</html>
代码语言:javascript
复制
# name:views.py
from django.shortcuts import render,HttpResponse
from django.forms import Form,fields,widgets
from django.core.exceptions import ValidationError

class LoginForm(Form):
    username = fields.CharField(
        required = True,
        max_length = 10,
        error_messages={"required":"该字段不能为空"},
        widget=widgets.TextInput(attrs={"placeholder":"请输入用户名","class":"form-control"})
    )
    password = fields.CharField(
        required = True,
        max_length=10,
        error_messages={"required":"密码字段不能为空","min_length":"密码最小长度为5"},
        widget=widgets.PasswordInput(attrs={"placeholder":"请输入密码","class":"form-control"})
    )
    RepeatPass = fields.CharField(
        required=True,
        max_length=10,
        error_messages={"required":"密码字段不能为空","min_length":"密码最小长度为5"},
        widget=widgets.PasswordInput(attrs={"placeholder":"重复输入密码","class":"form-control"})
    )

    # 自定义方法(局部钩子)密码必须包含字母和数字
    def clean_password(self):
        if self.cleaned_data.get("password").isdigit() or self.cleaned_data.get("password").isalpha():
            raise ValidationError("密码必须包含数字和字母")
        else:
            return self.cleaned_data["password"]
    # 自定义方法(全局钩子, 检验两个字段),检验两次密码是否一致
    def clean_RepeatPass(self):
        if self.cleaned_data.get("password") != self.cleaned_data.get("RepeatPass"):
            raise ValidationError("两次输入密码不正确")
        else:
            return self.cleaned_data

def index(request):
    if request.method =="GET":
        form = LoginForm()
        return render(request, "index.html", {"form": form})
    else:
        form = LoginForm(request.POST)
        if form.is_valid():
            # username = form.data['username']
            data = form.cleaned_data
            username = data.get("username")
            password = data.get("password")
            print(username,password)
            return render(request, "index.html", {"form": form})
    return render(request, "index.html", {"form": form})

其他常用Form表单:

代码语言:javascript
复制
<!--name: index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/" method="post">
        {% for field in form %}
            <p>{{ field.label_tag }} {{ field }} {{ field.errors.0 }}</p>
        {% endfor %}
        <input type="submit" value="提交" />
    </form>
</body>
</html>
代码语言:javascript
复制
# name: views.py
from django.shortcuts import render,HttpResponse
from django.forms import Form,fields,widgets

class MyForm(Form):
    hobby = fields.ChoiceField(
        label="单选框:",
        required=True,
        initial=1,                # 默认选择1号
        choices=( (1,"篮球"),(2,"足球"),(3,"乒乓球"),(4,"滚球")),
        widget=widgets.RadioSelect()
    )
    select = fields.ChoiceField(
        label="单选框(默认):",
        required=True,
        initial=1,
        choices=( (1,"篮球"),(2,"足球"),(3,"乒乓球"),(4,"滚球")),
        widget=widgets.Select()
    )
    multiple = fields.MultipleChoiceField(
        label="复选框",
        choices=((1, "篮球"), (2, "足球"), (3, "羽毛球"), (4, "排球")),
        initial=[2, 4],
        widget=widgets.SelectMultiple()
    )
    checkbox = fields.ChoiceField(
        label="单项复选框",
        initial="checked",  # 默认为勾选
        widget=widgets.CheckboxInput()
    )
    multselect = fields.MultipleChoiceField(
        label="多项复选框",
        choices=((1, "篮球"), (2, "足球"), (3, "羽毛球"), (4, "排球")),
        initial=[1, 3],
        widget=widgets.CheckboxSelectMultiple()
    )
    data = fields.DateField(
        label="选择日期",
        widget = widgets.DateInput(attrs={"type":"date"})
    )
def index(request):
    if request.method=="GET":
        form = MyForm()
        return render(request,"index.html",{"form":form})
    else:
        form = MyForm(request.POST)
        if form.is_valid():
            data = form.cleaned_data
            print(data.get("hobby"))
    return HttpResponse("hello lyshark")

Form实现用户注册:

代码语言:javascript
复制
<!--name: index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        <form action="/" method="post">
            <p>{{ form.username.label }} {{ form.username }}</p>
            <p>{{ form.password.label }} {{ form.password }}</p>
            <p>{{ form.mobile.label }} {{ form.mobile }} </p>
            <p>{{ form.email.label }} {{ form.email }} </p>
            <p>{{ form.text }} </p>
            <p><input type="submit" value="提交请求"></p>
        </form>
    </div>
</body>
</html>
代码语言:javascript
复制
# name: models.py
from django.db import models

class User(models.Model):
    id = models.AutoField(primary_key=True)
    username = models.CharField(max_length=64)
    password = models.CharField(max_length=32)
    mobile = models.CharField(max_length=32)
    email = models.EmailField(max_length=64)
    text = models.CharField(max_length=128)
代码语言:javascript
复制
# name: views.py
from django.shortcuts import render,HttpResponse
from MyWeb import models
from django.forms import Form,fields,widgets
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError

class UserForm(Form):
    username = fields.CharField(
        label = "账号: ",          # 给表单加一个标签
        required = True,           # 不允许字段为空值
        min_length=4,              # 设置最小长度
        max_length = 10,           # 设置最大长度
        validators=[ RegexValidator(r'^[0-9a-zA-Z]+$',"用户账号只能使用,0-9a-z") ],
        error_messages={"required":"该字段不能为空","invalid":"无效的用户名",
                        "min_length":"最小长度为5","max_length":"最大长度为10"},
        widget=widgets.TextInput(attrs={"placeholder":"请输入用户名","class":"form-control"})
    )
    password = fields.CharField(
        label = "密码: ",
        required = True,
        min_length=5,
        max_length=10,
        error_messages={"required":"密码字段不能为空","min_length":"密码最小长度为5"},
        widget=widgets.PasswordInput(attrs={"placeholder":"请输入密码","class":"form-control"})
    )
    mobile = fields.CharField(
        label = "手机: ",
        required=True,
        validators=[RegexValidator('[0-9]', "手机号必须是数字")],
        error_messages={"required":"该字段不能为空"},
        widget=widgets.TextInput(attrs={"placeholder": "手机号","class": "form-control"})
    )
    email = fields.EmailField(
        label="邮箱: ",
        required=True,
        error_messages={"required":"邮箱不能为空!!","invalid":"无效的邮箱"},
        widget=widgets.EmailInput(attrs={"placeholder": "邮箱", "class": "form-control"})
    )
    text = fields.CharField(
        required=True,
        widget=widgets.Textarea(attrs={"placeholder": "畅言,欢迎留言...", "class": "form-control",
                                       "style":"margin: 0px; width: 203px; height: 98px;"})
    )

def index(request):
    if request.method =="GET":
        form = UserForm()
        return render(request, "index.html", {"form": form})
    else:
        form = UserForm(request.POST)
        if form.is_valid():
            # username = form.data['username']
            data = form.cleaned_data
            username = data.get("username")

            is_exits = models.User.objects.filter(username="admin").count()
            if is_exits != 0:
                return HttpResponse("您注册的用户已存在")
            else:
                models.User.objects.create(**data)
                return HttpResponse("恭喜您的账号注册完成了")
        else:
            return render(request, "index.html", {"form": form.errors})
    return render(request, "index.html", {"form": form})

实现用户验证:

index.html

代码语言:javascript
复制
<head>
    <meta charset="UTF-8">
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>

<form action="/" method="post">
    <p> {{ form.email }}</p>
    <p> {{ form.code }} <a id="fetch_code" class="fetch-code" href="javascript:void(0);">获取验证码</a></p>
    <input type="submit" value="提交">
</form>


<script type="text/javascript">
    $("#fetch_code").click(function(){
        var email = $("#email").val();        // 获取到用户邮箱
        if(email.trim().length != 0)
        {
            $("#fetch_code").empty();
            $("#fetch_code").text("发送成功");
            $.ajax({
                url:"/send_msg/",
                type:"POST",
                data:{email:email},
                dataType:"json",
                success:function(recv){
                }
            })
        }
    })

</script>

models.py

代码语言:javascript
复制
from django.db import models

class SendMsg(models.Model):
    id = models.AutoField(primary_key=True)
    code = models.CharField(max_length=6)
    email = models.CharField(max_length=32, db_index=True)
    count = models.IntegerField(default=0)
    times = models.IntegerField(default=0)

class UserInfo(models.Model):
    id = models.AutoField(primary_key=True)
    username = models.CharField(max_length=32, unique=True)
    password = models.CharField(max_length=32)
    email = models.CharField(max_length=32, unique=True)

views.py

代码语言:javascript
复制
from django.shortcuts import render,HttpResponse
from django.core.mail import send_mail, send_mass_mail, EmailMultiAlternatives
import re,time,random
from MyWeb import models

def SendMail(rand,user):
    title = "本次注册验证码是: {} 十分钟以内有效.".format(rand)
    ret = send_mail("Django 邮件通知",title,"smtpwho@163.com",[user])
    if ret:
        return 1
    return 0
def send_msg(request):
    if request.method=="POST":
        email = request.POST.get("email")
        ret = re.match(r'^[0-9a-zA-Z\_\-]+(\.[0-9a-zA-Z\_\-]+)*@[0-9a-zA-Z]+(\.[0-9a-zA-Z]+){1,}$', email)
        if ret == None:
            print("不合法")
        else:
            ret = models.UserInfo.objects.filter(email=email).count()
            if ret == 1:
                print("你的邮箱已经注册了,请换一个..")
            else:
                ret = models.SendMsg.objects.filter(email=email).count()    # 查询出如果存在sendmsg表里,则不能让其注册
                if ret !=0:
                    print("等待超时,暂时不嫩注册..")
                    times = int(time.time())
                    if times >=models.SendMsg.objects.filter(email=email).values("times"):
                        print(times)
                    else:
                        print("时间还没到")

                else:
                    rand = random.randint(10000,20000)
                    if SendMail(rand,email):
                        times = int(time.time()+60)  # 一分钟只能注册一次
                        models.SendMsg.objects.create(email=email,code=rand,times=times)
    return render(request,"reg.html")

def reg(request):
    if request.method == "POST":
        email = request.POST.get("email")
        code = request.POST.get("code")
        ret = models.SendMsg.objects.filter(email=email).values("email","code")[0]
        if ret['email']==email and ret['code']==code:
            print("正确了")
            username = request.POST.get("username")
            password = request.POST.get("password")
            ret = models.UserInfo.objects.filter(username=username).count()
            if ret == 0:
                # 等于0说明没有这个用户,可以注册
                models.UserInfo.objects.create(username=username,password=password,email=email)
                print("注册完成了")
            else:
                print("这个账号重复了,请换一个...")
        else:
            print("验证码错误")
    return render(request, "reg.html")

urls.py

代码语言:javascript
复制
from django.contrib import admin
from django.urls import path
from MyWeb import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path("reg/",views.reg),
    path("send_msg/",views.send_msg)
]

settings.py

代码语言:javascript
复制
STATIC_URL = '/static/'
EMAIL_USER_TLS = True
EMAIL_PORT = 25
EMAIL_HOST = "smtp.163.com"
EMAIL_HOST_USER = "smtpwho@163.com"
EMAIL_HOST_PASSWORD = "123456789"

重写父类方法: 通过form表单重写init方法,实现数据库动态添加,前端动态显示,以两个选择框为例

代码语言:javascript
复制
# name: models.py
from django.db import models

class DBHost(models.Model):
    id = models.AutoField(primary_key=True)
    host = models.CharField(max_length=32)
    title = models.CharField(max_length=32)

# name:index.html
{{ form.title }}
{{ form.host }}
代码语言:javascript
复制
# name:views.py
from django.shortcuts import render
from django.forms import Form,fields,widgets
from MyWeb import models

class DBHost(Form):
    title = fields.IntegerField(widget=widgets.Select(choices=[]))
    host = fields.IntegerField(widget=widgets.SelectMultiple(choices=[]))

    # 重写父类的 __init__ 方法
    def __init__(self,*args,**kwargs):
        super(DBHost, self).__init__(*args,**kwargs)
        self.fields['title'].widget.choices = models.DBHost.objects.all().values_list("id","title")
        self.fields['host'].widget.choices = models.DBHost.objects.all().values_list("id", "host")

def index(request):
    form = DBHost()
    return render(request,"index.html",{"form":form})

给Form表单返回数据: Form表单可以返回默认数据,我们可以通过编号查询到指定数据的默认参数,并返回到编辑框中.

代码语言:javascript
复制
# name:views.py
from django.shortcuts import render
from django.forms import Form,fields,widgets
from MyWeb import models

class MyForm(Form):
    host = fields.CharField(required=True,widget=widgets.TextInput())
    title = fields.CharField(required=True, widget=widgets.TextInput())

def index(request):
    nid = request.GET.get("id")   # 通过ID获取到记录
    qset = models.DBHost.objects.filter(id=nid).values("host","title")
    dic = qset[0]  # 转为字典

    form = MyForm(dic) # 传递到前端编辑框中
    return render(request,"index.html",{"form":form})
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-12-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MVC 与 MTV
  • 创建第一个django项目
  • Django 初始化操作
  • Django 模板与视图
  • Django 表单操作
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档