当前位置:   article > 正文

Django Web开发基础知识

django web开发

Django是一个开源的Web框架,用于使用Python语言构建Web应用程序。它由一个高度可重用和可插拔的组件集合构成,使得开发者能够更快速、更轻松地构建功能强大的Web应用。Django采用了MVC(Model-View-Controller)的设计模式,但在Django中通常被称为MTV(Model-Template-View)。

以下是Django的一些关键特性和组件:

主要特性:

  1. 强大的ORM: Django内置了ORM系统,允许开发者使用Python代码而不是SQL语句与数据库交互。这简化了数据库操作和迁移过程。

  2. 模型-模板-视图(MTV)设计: Django采用了一种清晰的MTV设计模式,将应用程序的逻辑分成模型(数据层)、模板(表示层)和视图(业务逻辑层)。

  3. 自动化Admin界面: Django自动为模型生成管理界面,允许开发者轻松进行数据管理和查看。

  4. 强大的URL映射: Django使用灵活的URL映射机制,通过简单的配置,将URL映射到视图函数,使得URL管理变得简单而直观。

  5. 表单处理: Django提供了用于处理表单的强大机制,简化了用户输入的验证和处理。

  6. 安全性: Django内置了许多安全性功能,如防止CSRF攻击、XSS攻击和SQL注入。

  7. 多语言支持: Django支持多语言和多时区,允许开发者构建全球化的Web应用。

  8. 插件和可插拔应用: Django的可插拔应用机制使得开发者能够轻松集成第三方应用,并重用已有的代码。

Django组件:

  1. 模型(Model): 数据库的映射,定义了数据的结构和行为。

  2. 视图(View): 处理Web应用的业务逻辑,负责接收请求、处理数据、调用模板等。

  3. 模板(Template): 页面的呈现和展示,通过模板语言嵌入动态数据。

  4. 控制器(Controller): Django中的控制器的功能由视图和URL映射共同完成。

  5. URLconf: URL配置,将URL映射到对应的视图函数。

  6. 中间件(Middleware): 提供处理请求和响应的钩子,用于实现全局功能,如安全性检查、缓存等。

Django是一个全面且高度集成的框架,适用于各种规模的Web应用程序开发。其开发方式注重代码的清晰性、可维护性和可扩展性,为开发者提供了一套强大而灵活的工具。

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命令行参数。

  1. python manage.py shell #进入django shell
  2. python manage.py dbshell #进入django dbshell
  3. python manage.py check #检查django项目完整性
  4. python manage.py flush #清空数据库
  5. python manage.py compilemessages #编译语言文件
  6. python manage.py makemessages #创建语言文件
  7. python manage.py showmigrations #查看生成的数据库同步脚本
  8. python manage.py sqlflush #查看生成清空数据库的脚本
  9. python manage.py sqlmigrate #查看数据库同步的sql语句
  10. python manage.py dumpdata #导出数据
  11. python manage.py loaddata #导入数据
  12. python manage.py diffsettings #查看你的配置和django默认配置的不同之处

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

  1. MIDDLEWARE = [
  2. 'django.middleware.csrf.CsrfViewMiddleware', # 为了能够开心玩耍,把这个干掉
  3. ]
  4. INSTALLED_APPS = [
  5. 'django.contrib.admin',
  6. 'django.contrib.auth',
  7. 'django.contrib.contenttypes',
  8. 'django.contrib.sessions',
  9. 'django.contrib.messages',
  10. 'django.contrib.staticfiles',
  11. 'MyWeb.apps.MywebConfig' # 导入
  12. ]

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

  1. from MyWeb import views # 导入
  2. urlpatterns = [
  3. path('admin/', admin.site.urls),
  4. path('hello/',views.hello)
  5. ]

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

  1. from django.shortcuts import HttpResponse
  2. # Create your views here.
  3. # 这个request必须加,不然会报错
  4. def hello(request):
  5. return HttpResponse("<h1>hello lyshark</h1>")

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

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

  1. # Static files (CSS, JavaScript, Images)
  2. # https://docs.djangoproject.com/en/3.0/howto/static-files/
  3. # 这个路径是对应 src="/static/ 的别名
  4. # 如果这个路径改为 STATIC_URL = '/abc/' 那么<script src="/abc/xxx.js"></script>
  5. STATIC_URL = '/static/'
  6. STATICFILES_DIRS = (
  7. os.path.join(BASE_DIR,'static'),
  8. )

Django 初始化操作

初始化Django

  1. D:\> pip install django # 安装
  2. D:\> django-admin startproject MyProject # 创建项目
  3. D:\MyProject> django-admin startapp MyWeb # 创建APP
  4. D:\MyProject> python manage.py runserver 0.0.0.0:80 # 启动Django
  5. D:\MyProject> python manage.py shell # 进入Django交互shell
  6. D:\MyProject> python manage.py dbshell # 进入DBShell
  7. D:\MyProject> python manage.py check # 检查Django完整性

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

  1. MIDDLEWARE = [
  2. 'django.middleware.security.SecurityMiddleware',
  3. 'django.contrib.sessions.middleware.SessionMiddleware',
  4. 'django.middleware.common.CommonMiddleware',
  5. #'django.middleware.csrf.CsrfViewMiddleware', # 注释掉此行
  6. 'django.contrib.auth.middleware.AuthenticationMiddleware',
  7. ]
  8. INSTALLED_APPS = [
  9. 'django.contrib.admin',
  10. 'django.contrib.auth',
  11. 'django.contrib.contenttypes',
  12. 'django.contrib.sessions',
  13. 'django.contrib.messages',
  14. 'django.contrib.staticfiles',
  15. 'MyWeb.apps.MywebConfig' # 添加此行,导入我们的APP的名字
  16. ]

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

  1. from MyWeb import views
  2. urlpatterns = [
  3. path('admin/', admin.site.urls),
  4. path("hello/",views.hello,name="hello")
  5. ]

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

  1. from django.shortcuts import HttpResponse
  2. def hello(request):
  3. return HttpResponse("<h1>hello lyshark</h1>")

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

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

Django 模板与视图

简单的路由编写

  1. urlpatterns = [
  2. path('admin/', admin.site.urls),
  3. path('',views.index,name="index"), # 一条访问主站的路由
  4. path('login/id=<int:id>&name=<str:name>',views.login,name="login"), # 名称后面传递参数
  5. path('add/<int:x>/<int:y>/',views.add,name="add") # 路径中传递参数
  6. ]
  7. from django.shortcuts import render,HttpResponse
  8. def index(request):
  9. return render(request,"index.html")
  10. def login(request, id, name):
  11. return HttpResponse("用户ID{} , 用户名{} ".format(id,name))
  12. def add(request,x,y):
  13. temp = int(x)+int(y)
  14. return HttpResponse("相加结果:{}".format(temp))

使用模板传递简单的参数

  1. **用户名: {{ user }} 密码:{{ pasd }} 标题:{{ title }}:**
  2. def index(request):
  3. username = "lyshark"
  4. password = "123123"
  5. title = "hello lyshark"
  6. return render(request,"index.html",{"user":username,"pasd":password,"title":title})

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

  1. **用户名: {{ user }} 密码:{{ pasd }} 标题:{{ title }}:**
  2. def index(request):
  3. username = "admin"
  4. password = "123123"
  5. title = "hello lyshark"
  6. dict = {
  7. "user": username,
  8. "pasd": password,
  9. "title": title
  10. }
  11. return render(request,"index.html",dict)

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

  1. **站点名称:{{ info.site }} 站点描述:{{ info.content }}:**
  2. def index(request):
  3. info = {"site":"blib.cn","content":"hello lyshark"}
  4. return render(request,"index.html",{"info":info})

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

  1. {% for item in total %}
  2. **打印数据: {{ item }}:**<br>
  3. {% endfor %}
  4. def index(request):
  5. lists = ["HTML","CSS","JAVASCRIPT","Python","JQuery"]
  6. return render(request,"index.html",{"total":lists})

通过for语句倒序循环打印

  1. {% for item in total reversed%}
  2. **打印数据: {{ item }}:**<br>
  3. {% endfor %}
  4. def index(request):
  5. lists = ["1","2","3","4","5"]
  6. return render(request,"index.html",{"total":lists})

通过使用for循环遍历字典

  1. {% for key,value in info.items %}
  2. {{ key }} : {{ value }}
  3. {% endfor %}
  4. def index(request):
  5. info = {"site":"blib.cn","content":"hello lyshark"}
  6. info1 = {"site": "blib.cn", "content": "hello admin"}
  7. return render(request,"index.html",{"info":info,"info1":info1})

简单的路径拼接

  1. <a href="{{ request.path }}?uid=1">当前网址加参数</a>
  2. <!--获取当前路径 拼接成 /add/4/5-->
  3. {{ request.path }}{% url 'add' 4 5 %}
  4. def add(request,x,y):
  5. temp = int(x)+int(y)
  6. return HttpResponse("相加结果:{}".format(temp))
  7. def index(request):
  8. return render(request,"index.html")

判断用户是否登录

  1. {% if request.user.is_authenticated %}
  2. {{ request.user.username }},您好!
  3. {% else %}
  4. 请登陆,这里放登陆链接
  5. {% endif %}

使用if语句判断数据

  1. {% if username == "lyshark" and password == "123123" %}
  2. **恭喜你:**
  3. {% elif username == "admin" or password == "123123" %}
  4. **欢迎管理员:**
  5. {% else %}
  6. **这个都不是:**
  7. {% endif %}
  8. def index(request):
  9. username = "admin"
  10. password = "123123"
  11. return render(request,"index.html",{"username":username,"password":password})

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

  1. {% if 1 in list %}
  2. **在里面:**
  3. {% elif 10 not in list %}
  4. ** 不在里面:**
  5. {% endif %}
  6. def index(request):
  7. list = [1,2,3,4,5]
  8. return render(request,"index.html",{"list":list})

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

  1. {% for item in info %}
  2. {% if forloop.first %}
  3. **开始了:**
  4. {% endif %}
  5. {{ forloop.counter }} : {{ item }}<br>
  6. {% if forloop.last %}
  7. **最后了:**
  8. {% endif %}
  9. {% endfor %}
  10. def index(request):
  11. list = map(str,range(100))
  12. return render(request,"index.html",{"info":list})
  13. forloop.counter 索引从 1 开始算
  14. forloop.counter0 索引从 0 开始算
  15. forloop.revcounter 索引从最大长度到 1
  16. forloop.revcounter0 索引从最大长度到 0
  17. forloop.first 当遍历的元素为第一项时为真
  18. forloop.last 当遍历的元素为最后一项时为真
  19. forloop.parentloop
  20. 用在嵌套的 for 循环中,获取上一层 for 循环的 forloop

常用的过滤器

  1. ** 列表长度: {{ total | length }}:**<br>
  2. ** 输出大小: {{ size | filesizeformat }}:**<br>
  3. ** 输出时间: {{ date | date:"Y-m-d" }}:**<br>
  4. ** 首字母大写: {{ title | capfirst }}:**<br>
  5. ** 从字符串中移除hello字符: {{title | cut:"hello" }}:**<br>
  6. ** 显示字符串第一个元素: {{ total | first }}:**<br>
  7. ** 显示字符串最后一个元素: {{ total | last }}:**<br>
  8. ** 大小写转换(upper/lower): {{ title | upper }}:**<br>
  9. ** 对数据切片: {{ title | slice:"2:-1" }}:**<br>
  10. **截断字符:{{ title | truncatechars:5 }}:**<br>
  11. **截断单词:{{ title | truncatewords:1 }}:**
  12. def index(request):
  13. filesize = 10240
  14. title = "hello lyshark"
  15. date = datetime.datetime.now()
  16. lists = ["1","2","3","4","5"]
  17. return render(request,"index.html",{"total":lists,"size":filesize,"date":date,"title":title})

自定义过滤器与标签

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

  1. MyWeb/
  2. __init__.py
  3. models.py
  4. templatetags/
  5. __init__.py
  6. mysimple.py
  7. views.py

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

  1. from django import template
  2. from django.utils.safestring import mark_safe
  3. register = template.Library() # 此处必须这样写
  4. # simple_tag(自定义标签):不会限制传参,但不支持if
  5. @register.simple_tag
  6. def simple_time(var1,var2,var3):
  7. temp = int(var1)+int(var2)+int(var3)
  8. return temp
  9. # filter(自定义过滤器):限制传参2个,但支持if
  10. @register.filter
  11. def My_filter(value, arg):
  12. # 传递一个参数的过滤器
  13. return str.upper(value) + arg

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

  1. # name: views.py
  2. def index(request):
  3. title = "hello"
  4. return render(request,"index.html",{"title":title})
  5. # name: index.html
  6. <!--引入自定义的过滤器-->
  7. {% load mysimple %}
  8. **自定义标签返回数值: {% simple_time 10 20 30 %}:** <!-- 传递多个参数 -->
  9. **传递一个参数的过滤器: {{ title | My_filter:'lyshark' }}:** <!-- 传递一个参数 -->

模板与模板继承

  1. 母板: {% block title %}{% endblock %}
  2. 子板继承: {% extends "base.html" %}
  3. 子板中使用其他模板: {% include "xx.html" %}
  4. 设置标题: {% block title %}{% endblock %}
  5. 使用CSS资源: {% block css %} {% endblock %}
  6. 使用JS资源: {% block js %} {% endblock %}

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

  1. <html>
  2. <head>
  3. <meta charset="UTF-8">
  4. {% block css %}{% endblock %}
  5. </head>
  6. <body>
  7. <div class="pg-body">
  8. <div class="body-menu">
  9. <ul>
  10. <li><a href="/user">用户管理</a></li>
  11. <li><a href="/hosts">资产管理</a></li>
  12. </ul>
  13. </div>
  14. <div class="body-content">
  15. {% block body %}{% endblock %} <!--占位符,用于填充子版块-->
  16. </div>
  17. </div>
  18. {% block js %}{% endblock %}
  19. </body>
  20. </html>

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

  1. {% extends 'base.html' %}
  2. {% block js %} {% endblock %}
  3. {% block css %} {% endblock %}
  4. {% block body %}
  5. <table>
  6. {% for item in host %}
  7. <tr>
  8. <td>{{ item.hostname }}</td>
  9. <td>{{ item.port }}</td>
  10. </tr>
  11. {% endfor %}
  12. </table>
  13. {% endblock %}

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

  1. {% extends 'base.html' %}
  2. {% block js %} {% endblock %}
  3. {% block css %} {% endblock %}
  4. {% block body %}
  5. <ul>
  6. {% for item in user_list %}
  7. <li>{{ item.username }},{{ item.salary }}</li>
  8. {% endfor %}
  9. </ul>
  10. {% endblock %}

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

  1. from django.contrib import admin
  2. from django.urls import path
  3. from MyWeb import views
  4. urlpatterns = [
  5. path('admin/', admin.site.urls),
  6. path('',views.index,name="index"),
  7. path('hosts/',views.hosts,name="hosts"),
  8. path('user/',views.userinfo,name="user")
  9. ]

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

  1. from django.shortcuts import render
  2. from django.shortcuts import HttpResponse
  3. def index(request):
  4. return render(request,"base.html")
  5. def hosts(request):
  6. hosts_list = []
  7. for i in range(10):
  8. temp = {'hostname':'192.168.1.'+str(i),'port':80}
  9. hosts_list.append(temp)
  10. return render(request,'hosts.html',{'host':hosts_list})
  11. def userinfo(request):
  12. user_list = []
  13. for i in range(10):
  14. temp = {'username': 'user' + str(i),'salary':80}
  15. user_list.append(temp)
  16. return render(request,'user.html',{'user_list':user_list})

简单的用户登录

  1. # name:login.html
  2. <!DOCTYPE html>
  3. <body lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Title</title>
  7. </head>
  8. <form action="{% url 'login' %}" method="post"> # 通过模板获取到login的试图
  9. <input type="text" name="username" />
  10. <input type="text" name="password" />
  11. <input type="submit" name="提交"/>
  12. </form>
  13. </body>
  14. </html>
  15. # name: urls.py
  16. from django.contrib import admin
  17. from django.urls import path
  18. from MyWeb import views
  19. urlpatterns = [
  20. path('admin/', admin.site.urls),
  21. path('login/', views.login, name="login") # name是给视图起一个名字
  22. ]
  23. # name:views.py
  24. from django.shortcuts import render,HttpResponse
  25. def login(request):
  26. if request.method == "GET":
  27. return render(request,"index.html")
  28. elif request.method == "POST":
  29. username = request.POST.get("username")
  30. password = request.POST.get("password")
  31. return HttpResponse("您提交的用户:{} 密码:{}".format(username,password))

Django 表单操作

普通Form表单的提交

  1. <!-- name:index.html -->
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Title</title>
  7. </head>
  8. <body>
  9. <form action="/" method="post">
  10. <p>账号:<input type="text" name="username"><span>{{ error.username }}</span></p>
  11. <p>密码:<input type="password" name="password"><span>{{ error.password }}</span></p>
  12. <input type="submit" value="提交请求">
  13. </form>
  14. </body>
  15. </html>
  1. # name: views.py
  2. from django.shortcuts import render,HttpResponse
  3. def index(request):
  4. if request.method == "GET":
  5. return render(request,"index.html")
  6. else:
  7. username = request.POST.get("username")
  8. password = request.POST.get("password")
  9. error = {"username":"","password":""}
  10. if len(username) > 10:
  11. error["username"]="用户名不能大于10"
  12. if len(password) < 5:
  13. error["password"] = "密码不能小于5"
  14. return render(request,"index.html",{"error":error})

实现单项选择框

  1. <form action="/index/" method="post">
  2. 选择A:
  3. <select name="tag_select_a">
  4. {% for item in total_a %}
  5. <option value = "{{ item }}"> {{ item }} </option>
  6. {% endfor %}
  7. </select>
  8. 选择B:
  9. <select name="tag_select_b">
  10. {% for item in total_b %}
  11. <option value = "{{ item }}"> {{ item }} </option>
  12. {% endfor %}
  13. </select>
  14. <input type="submit" value="提交选择">
  15. </form>
  1. def index(request):
  2. if request.method == "GET":
  3. tag_select_a = ["HTML", "CSS", "JAVASCRIPT", "Python", "JQuery"]
  4. tag_select_b = ["MySQL","Oracle","MSSQL"]
  5. return render(request, "index.html", {"total_a": tag_select_a,"total_b": tag_select_b})
  6. elif request.method == "POST":
  7. select_a = request.POST.get("tag_select_a")
  8. select_b = request.POST.get("tag_select_b")
  9. return HttpResponse("选择A: {} 选择B: {}".format(select_a,select_b))<b>普通Form表单的提交</b>

提交账号密码

  1. <!-- name:index.html -->
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Title</title>
  7. </head>
  8. <body>
  9. <form action="/" method="post">
  10. <p>账号:<input type="text" name="username"><span>{{ error.username }}</span></p>
  11. <p>密码:<input type="password" name="password"><span>{{ error.password }}</span></p>
  12. <input type="submit" value="提交请求">
  13. </form>
  14. </body>
  15. </html>
  1. # name: views.py
  2. from django.shortcuts import render,HttpResponse
  3. def index(request):
  4. if request.method == "GET":
  5. return render(request,"index.html")
  6. else:
  7. username = request.POST.get("username")
  8. password = request.POST.get("password")
  9. error = {"username":"","password":""}
  10. if len(username) > 10:
  11. error["username"]="用户名不能大于10"
  12. if len(password) < 5:
  13. error["password"] = "密码不能小于5"
  14. return render(request,"index.html",{"error":error})

Form实现登录表单

  1. <!--name:index.html-->
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Title</title>
  7. </head>
  8. <body>
  9. <form action="/" method="post" novalidate>
  10. <p>账号: {{ form.username }} {{ form.username.errors.0 }}</p>
  11. <p>密码: {{ form.password }} {{ form.errors.password }}</p>
  12. <p>重复: {{ form.RepeatPass }} {{ form.errors.RepeatPass }}</p>
  13. <input type="submit" value="提交">
  14. </form>
  15. </body>
  16. </html>
  1. # name:views.py
  2. from django.shortcuts import render,HttpResponse
  3. from django.forms import Form,fields,widgets
  4. from django.core.exceptions import ValidationError
  5. class LoginForm(Form):
  6. username = fields.CharField(
  7. required = True,
  8. max_length = 10,
  9. error_messages={"required":"该字段不能为空"},
  10. widget=widgets.TextInput(attrs={"placeholder":"请输入用户名","class":"form-control"})
  11. )
  12. password = fields.CharField(
  13. required = True,
  14. max_length=10,
  15. error_messages={"required":"密码字段不能为空","min_length":"密码最小长度为5"},
  16. widget=widgets.PasswordInput(attrs={"placeholder":"请输入密码","class":"form-control"})
  17. )
  18. RepeatPass = fields.CharField(
  19. required=True,
  20. max_length=10,
  21. error_messages={"required":"密码字段不能为空","min_length":"密码最小长度为5"},
  22. widget=widgets.PasswordInput(attrs={"placeholder":"重复输入密码","class":"form-control"})
  23. )
  24. # 自定义方法(局部钩子)密码必须包含字母和数字
  25. def clean_password(self):
  26. if self.cleaned_data.get("password").isdigit() or self.cleaned_data.get("password").isalpha():
  27. raise ValidationError("密码必须包含数字和字母")
  28. else:
  29. return self.cleaned_data["password"]
  30. # 自定义方法(全局钩子, 检验两个字段),检验两次密码是否一致
  31. def clean_RepeatPass(self):
  32. if self.cleaned_data.get("password") != self.cleaned_data.get("RepeatPass"):
  33. raise ValidationError("两次输入密码不正确")
  34. else:
  35. return self.cleaned_data
  36. def index(request):
  37. if request.method =="GET":
  38. form = LoginForm()
  39. return render(request, "index.html", {"form": form})
  40. else:
  41. form = LoginForm(request.POST)
  42. if form.is_valid():
  43. # username = form.data['username']
  44. data = form.cleaned_data
  45. username = data.get("username")
  46. password = data.get("password")
  47. print(username,password)
  48. return render(request, "index.html", {"form": form})
  49. return render(request, "index.html", {"form": form})

其他常用Form表单

  1. <!--name: index.html-->
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Title</title>
  7. </head>
  8. <body>
  9. <form action="/" method="post">
  10. {% for field in form %}
  11. <p>{{ field.label_tag }} {{ field }} {{ field.errors.0 }}</p>
  12. {% endfor %}
  13. <input type="submit" value="提交" />
  14. </form>
  15. </body>
  16. </html>
  1. # name: views.py
  2. from django.shortcuts import render,HttpResponse
  3. from django.forms import Form,fields,widgets
  4. class MyForm(Form):
  5. hobby = fields.ChoiceField(
  6. label="单选框:",
  7. required=True,
  8. initial=1, # 默认选择1号
  9. choices=( (1,"篮球"),(2,"足球"),(3,"乒乓球"),(4,"滚球")),
  10. widget=widgets.RadioSelect()
  11. )
  12. select = fields.ChoiceField(
  13. label="单选框(默认):",
  14. required=True,
  15. initial=1,
  16. choices=( (1,"篮球"),(2,"足球"),(3,"乒乓球"),(4,"滚球")),
  17. widget=widgets.Select()
  18. )
  19. multiple = fields.MultipleChoiceField(
  20. label="复选框",
  21. choices=((1, "篮球"), (2, "足球"), (3, "羽毛球"), (4, "排球")),
  22. initial=[2, 4],
  23. widget=widgets.SelectMultiple()
  24. )
  25. checkbox = fields.ChoiceField(
  26. label="单项复选框",
  27. initial="checked", # 默认为勾选
  28. widget=widgets.CheckboxInput()
  29. )
  30. multselect = fields.MultipleChoiceField(
  31. label="多项复选框",
  32. choices=((1, "篮球"), (2, "足球"), (3, "羽毛球"), (4, "排球")),
  33. initial=[1, 3],
  34. widget=widgets.CheckboxSelectMultiple()
  35. )
  36. data = fields.DateField(
  37. label="选择日期",
  38. widget = widgets.DateInput(attrs={"type":"date"})
  39. )
  40. def index(request):
  41. if request.method=="GET":
  42. form = MyForm()
  43. return render(request,"index.html",{"form":form})
  44. else:
  45. form = MyForm(request.POST)
  46. if form.is_valid():
  47. data = form.cleaned_data
  48. print(data.get("hobby"))
  49. return HttpResponse("hello lyshark")

Form实现用户注册

  1. <!--name: index.html-->
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Title</title>
  7. </head>
  8. <body>
  9. <div>
  10. <form action="/" method="post">
  11. <p>{{ form.username.label }} {{ form.username }}</p>
  12. <p>{{ form.password.label }} {{ form.password }}</p>
  13. <p>{{ form.mobile.label }} {{ form.mobile }} </p>
  14. <p>{{ form.email.label }} {{ form.email }} </p>
  15. <p>{{ form.text }} </p>
  16. <p><input type="submit" value="提交请求"></p>
  17. </form>
  18. </div>
  19. </body>
  20. </html>
  1. # name: models.py
  2. from django.db import models
  3. class User(models.Model):
  4. id = models.AutoField(primary_key=True)
  5. username = models.CharField(max_length=64)
  6. password = models.CharField(max_length=32)
  7. mobile = models.CharField(max_length=32)
  8. email = models.EmailField(max_length=64)
  9. text = models.CharField(max_length=128)
  1. # name: views.py
  2. from django.shortcuts import render,HttpResponse
  3. from MyWeb import models
  4. from django.forms import Form,fields,widgets
  5. from django.core.validators import RegexValidator
  6. from django.core.exceptions import ValidationError
  7. class UserForm(Form):
  8. username = fields.CharField(
  9. label = "账号: ", # 给表单加一个标签
  10. required = True, # 不允许字段为空值
  11. min_length=4, # 设置最小长度
  12. max_length = 10, # 设置最大长度
  13. validators=[ RegexValidator(r'^[0-9a-zA-Z]+$',"用户账号只能使用,0-9a-z") ],
  14. error_messages={"required":"该字段不能为空","invalid":"无效的用户名",
  15. "min_length":"最小长度为5","max_length":"最大长度为10"},
  16. widget=widgets.TextInput(attrs={"placeholder":"请输入用户名","class":"form-control"})
  17. )
  18. password = fields.CharField(
  19. label = "密码: ",
  20. required = True,
  21. min_length=5,
  22. max_length=10,
  23. error_messages={"required":"密码字段不能为空","min_length":"密码最小长度为5"},
  24. widget=widgets.PasswordInput(attrs={"placeholder":"请输入密码","class":"form-control"})
  25. )
  26. mobile = fields.CharField(
  27. label = "手机: ",
  28. required=True,
  29. validators=[RegexValidator('[0-9]', "手机号必须是数字")],
  30. error_messages={"required":"该字段不能为空"},
  31. widget=widgets.TextInput(attrs={"placeholder": "手机号","class": "form-control"})
  32. )
  33. email = fields.EmailField(
  34. label="邮箱: ",
  35. required=True,
  36. error_messages={"required":"邮箱不能为空!!","invalid":"无效的邮箱"},
  37. widget=widgets.EmailInput(attrs={"placeholder": "邮箱", "class": "form-control"})
  38. )
  39. text = fields.CharField(
  40. required=True,
  41. widget=widgets.Textarea(attrs={"placeholder": "畅言,欢迎留言...", "class": "form-control",
  42. "style":"margin: 0px; width: 203px; height: 98px;"})
  43. )
  44. def index(request):
  45. if request.method =="GET":
  46. form = UserForm()
  47. return render(request, "index.html", {"form": form})
  48. else:
  49. form = UserForm(request.POST)
  50. if form.is_valid():
  51. # username = form.data['username']
  52. data = form.cleaned_data
  53. username = data.get("username")
  54. is_exits = models.User.objects.filter(username="admin").count()
  55. if is_exits != 0:
  56. return HttpResponse("您注册的用户已存在")
  57. else:
  58. models.User.objects.create(**data)
  59. return HttpResponse("恭喜您的账号注册完成了")
  60. else:
  61. return render(request, "index.html", {"form": form.errors})
  62. return render(request, "index.html", {"form": form})

实现用户验证

index.html

  1. <head>
  2. <meta charset="UTF-8">
  3. <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
  4. </head>
  5. <body>
  6. <form action="/" method="post">
  7. <p> {{ form.email }}</p>
  8. <p> {{ form.code }} <a id="fetch_code" class="fetch-code" href="javascript:void(0);">获取验证码</a></p>
  9. <input type="submit" value="提交">
  10. </form>
  11. <script type="text/javascript">
  12. $("#fetch_code").click(function(){
  13. var email = $("#email").val(); // 获取到用户邮箱
  14. if(email.trim().length != 0)
  15. {
  16. $("#fetch_code").empty();
  17. $("#fetch_code").text("发送成功");
  18. $.ajax({
  19. url:"/send_msg/",
  20. type:"POST",
  21. data:{email:email},
  22. dataType:"json",
  23. success:function(recv){
  24. }
  25. })
  26. }
  27. })
  28. </script>

models.py

  1. from django.db import models
  2. class SendMsg(models.Model):
  3. id = models.AutoField(primary_key=True)
  4. code = models.CharField(max_length=6)
  5. email = models.CharField(max_length=32, db_index=True)
  6. count = models.IntegerField(default=0)
  7. times = models.IntegerField(default=0)
  8. class UserInfo(models.Model):
  9. id = models.AutoField(primary_key=True)
  10. username = models.CharField(max_length=32, unique=True)
  11. password = models.CharField(max_length=32)
  12. email = models.CharField(max_length=32, unique=True)

views.py

  1. from django.shortcuts import render,HttpResponse
  2. from django.core.mail import send_mail, send_mass_mail, EmailMultiAlternatives
  3. import re,time,random
  4. from MyWeb import models
  5. def SendMail(rand,user):
  6. title = "本次注册验证码是: {} 十分钟以内有效.".format(rand)
  7. ret = send_mail("Django 邮件通知",title,"smtpwho@163.com",[user])
  8. if ret:
  9. return 1
  10. return 0
  11. def send_msg(request):
  12. if request.method=="POST":
  13. email = request.POST.get("email")
  14. ret = re.match(r'^[0-9a-zA-Z\_\-]+(\.[0-9a-zA-Z\_\-]+)*@[0-9a-zA-Z]+(\.[0-9a-zA-Z]+){1,}$', email)
  15. if ret == None:
  16. print("不合法")
  17. else:
  18. ret = models.UserInfo.objects.filter(email=email).count()
  19. if ret == 1:
  20. print("你的邮箱已经注册了,请换一个..")
  21. else:
  22. ret = models.SendMsg.objects.filter(email=email).count() # 查询出如果存在sendmsg表里,则不能让其注册
  23. if ret !=0:
  24. print("等待超时,暂时不嫩注册..")
  25. times = int(time.time())
  26. if times >=models.SendMsg.objects.filter(email=email).values("times"):
  27. print(times)
  28. else:
  29. print("时间还没到")
  30. else:
  31. rand = random.randint(10000,20000)
  32. if SendMail(rand,email):
  33. times = int(time.time()+60) # 一分钟只能注册一次
  34. models.SendMsg.objects.create(email=email,code=rand,times=times)
  35. return render(request,"reg.html")
  36. def reg(request):
  37. if request.method == "POST":
  38. email = request.POST.get("email")
  39. code = request.POST.get("code")
  40. ret = models.SendMsg.objects.filter(email=email).values("email","code")[0]
  41. if ret['email']==email and ret['code']==code:
  42. print("正确了")
  43. username = request.POST.get("username")
  44. password = request.POST.get("password")
  45. ret = models.UserInfo.objects.filter(username=username).count()
  46. if ret == 0:
  47. # 等于0说明没有这个用户,可以注册
  48. models.UserInfo.objects.create(username=username,password=password,email=email)
  49. print("注册完成了")
  50. else:
  51. print("这个账号重复了,请换一个...")
  52. else:
  53. print("验证码错误")
  54. return render(request, "reg.html")

urls.py

  1. from django.contrib import admin
  2. from django.urls import path
  3. from MyWeb import views
  4. urlpatterns = [
  5. path('admin/', admin.site.urls),
  6. path("reg/",views.reg),
  7. path("send_msg/",views.send_msg)
  8. ]

settings.py

  1. STATIC_URL = '/static/'
  2. EMAIL_USER_TLS = True
  3. EMAIL_PORT = 25
  4. EMAIL_HOST = "smtp.163.com"
  5. EMAIL_HOST_USER = "smtpwho@163.com"
  6. EMAIL_HOST_PASSWORD = "123456789"

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

  1. # name: models.py
  2. from django.db import models
  3. class DBHost(models.Model):
  4. id = models.AutoField(primary_key=True)
  5. host = models.CharField(max_length=32)
  6. title = models.CharField(max_length=32)
  7. # name:index.html
  8. {{ form.title }}
  9. {{ form.host }}
  1. # name:views.py
  2. from django.shortcuts import render
  3. from django.forms import Form,fields,widgets
  4. from MyWeb import models
  5. class DBHost(Form):
  6. title = fields.IntegerField(widget=widgets.Select(choices=[]))
  7. host = fields.IntegerField(widget=widgets.SelectMultiple(choices=[]))
  8. # 重写父类的 __init__ 方法
  9. def __init__(self,*args,**kwargs):
  10. super(DBHost, self).__init__(*args,**kwargs)
  11. self.fields['title'].widget.choices = models.DBHost.objects.all().values_list("id","title")
  12. self.fields['host'].widget.choices = models.DBHost.objects.all().values_list("id", "host")
  13. def index(request):
  14. form = DBHost()
  15. return render(request,"index.html",{"form":form})

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

  1. # name:views.py
  2. from django.shortcuts import render
  3. from django.forms import Form,fields,widgets
  4. from MyWeb import models
  5. class MyForm(Form):
  6. host = fields.CharField(required=True,widget=widgets.TextInput())
  7. title = fields.CharField(required=True, widget=widgets.TextInput())
  8. def index(request):
  9. nid = request.GET.get("id") # 通过ID获取到记录
  10. qset = models.DBHost.objects.filter(id=nid).values("host","title")
  11. dic = qset[0] # 转为字典
  12. form = MyForm(dic) # 传递到前端编辑框中
  13. return render(request,"index.html",{"form":form})
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/73806
推荐阅读
相关标签
  

闽ICP备14008679号