Django学习笔记
安装django
-
pip3 install django
删除django
-
pip3 uninstall django
创建django项目
-
# django-admin startproject 创建的项目名 django-admin startproject mywebsite
运行django项目
-
# 运行时需要进入到django目录 python manage.py runserver
创建django-app(即django应用)
-
# python manage.py startapp 应用名称 python manage.py startapp news
注册django-app
-
# 在项目下的settings文件中进行注册 # 在INSTALLED_APPS中增加需要注册的应用名,如上news
修改django界面默认语言为中文
# 在项目下的settings文件中进行设置
# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-hans'
创建django后台管理员用户与密码
python manage.py createsuperuser
MVT
M——models
主要封装数据库,对数据库进行访问,对数据进行增删改查。
V——views
进行业务逻辑处理
T——templates
主要进行展示
URL
url标准语法
protocol://hostname[:port]/path/[:parameters][?query]#fragment
- protocol:协议,如http、https、ftp、mailto、ldap、file、news、telnet
- hostname:ip地址
- port:端口
- path:路径
- parameters:参数
- query:查询
- fragment:锚点
Path
path()标准语法
path(<route>, <view>, [name=None], [**kwargs])
- route:表示路径,从端口以后的URL地址,到/结束
- view:表示route匹配成功后,需要调用的视图,view必须是个函数,如果class必须使用as_view()转换为函数
- name:表示视图的别名
- **kwags:以字典形式传递的参数
路径转换器
path('AlexLu/Eva/<html>', views.web, name='web'),
# 其中<html>为传递给函数views.web的参数
- str —— 用法:
<str:html>
匹配一个非空字符及,除去 ’/‘ ,默认使用的是这种方式 - int ——
<int:html>
匹配0或正整数 - slug ——
<slug:html>
由ASCII字母或数字组成,通过 ’-‘ 链接的字符串 - uuid ——
<uuid:html>
uuid格式的字符串 - path ——
<path:html>
匹配一个非空字符串,包括 ’/‘
path('index/<str:html>', views.index, name='index'),
path('index/<path:home>', views.home, name='home'),
path('page/<int:page>', views.page, name='page'),
path('index/<int:numa>/<int:numb>', views.sum, name='sum'),
path('slug/<slug:slugstr>', views.slugstr, name='slugstr'),
path('uuid/<uuid:uuid>', views.uuid, name='uuid'),
# ---------------------------------------------------------------------
def index(request, html):
return HttpResponse(html)
def home(request, home):
return HttpResponse('<h1>{}</h1>'.format(home))
def page(request, page):
return HttpResponse('<h1>{}</h1>'.format(page))
def sum(request, numa, numb):
return HttpResponse('<h1>{}</h1>'.format(numa+numb))
def slugstr(request, slugstr):
return HttpResponse('<h1>{}</h1>'.format(slugstr))
def uuid(request, uuid):
return HttpResponse('<h1 >{}</h1>'.format(uuid))
include
include的三种语法
1. module
- include(module, namespace=None)
2. namespace
- include(pattern_list)
3. pattern_list
- include((pattern_list, app_namespace), namespace=None)
include用法说明
- module —— 表示一个模块(模型)文件
- namespace —— 实例命名空间
- pattern_list —— 必须是一个可迭代的path()或re_path()清单
- app_namespace —— app命名空间
URL地址重定向
redirect(to, permanent=False, *args, **kwargs)
- to —— 指需要重新定位的位置,这个位置可以是一个视图,可以是一个url地址,也可以是一个模块
- permanent —— 默认为False,用来表示是否永久重定向
Reverse
reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)
HTTP
HttpResponse
HttpResponse(content, content_type=None, status=None, charset=None, reason=None *args, **kwargs)
- content —— 返回给视图函数的内容
- content_type —— 返回给视图函数的类型
- text/html —— HTML文本字符串
- text/plain —— 纯文本
- text/css
- text/javascript
- application/xml —— xml文本
- application/json —— json文本
- multipart/form-data —— 上传文本
- status —— Http响应代码
- 200 —— 表示成功
- 404 —— 页面找不到
- charset —— 字符编码设置
常见的几种错误视图代码
- 404 page not found
- 找不到相应的页面
- 500 server error
- 服务器错误
- 400 bad request
- 无效的请求
- 403 HTTP forbidden
- HTTP禁止访问,权限不足
- 200 OK
- 请求成功
Http请求方式
- 介绍 —— HTTP 协议定义一些方法,以指明为获取客户端(如您的浏览器或我们的 CheckUpDown 机器人)所指定的具体网址资源而需要在 Web 服务器上执行的动作。则这些方法如下:
- OPTIONS( 选项 ) :查找适用于一个特定网址资源的通讯选择。 在不需执行具体的涉及数据传输的动作情况下, 允许客户端来确定与资源相关的选项以及 / 或者要求, 或是一个服务器的性能。
- GET( 获取 ) :检索由网址资源所确定的信息,如获取一个特定的网页或图片。这是最常用的方法。
- HEAD( 头 ) :除了服务器只反馈标头信息而不是网址资源所确定的信息本身外, 基本同于 GET ( 获取 ) 。 可用于获取一个请求所要求的响应实体的元信息 ( metainformation) ,而不需传输响应实体本身。 经常用来测试超文本链接的有效性, 可达性, 和最近的修改。
- POST( 投寄 ) :将数据提交到 Web 服务器,如 1 )在电子公告板,新闻组中,或向 邮件名单发送信息, 2 )提供输入数据 - 通常由一个公共网关接口(CGI) 表, 到 一个数据处理进程, 3 )直接将记录添加到一个数据库中。
- PUT( 放置 ) :将一个具体网址的数据设置( 置入 / 替换)成客户提交的新数据。例如,将新的网页上载给服务器。
- DELETE( 删除 ) :删除与网址资源相关的数据。例如,删除网页。
- TRACE( 跟踪 ) :运行请求信息的一个远程应用层回送。 实际上是一个 'ping', 用以测试 Web 服务器正在从客户端接收什么数据。
- CONNECT( 连接 ) :保留以便通过代理服务器和隧道一起使用(如 SSL )。这种方法只在 HTTP 1.1 版中定义, 而在先前的 1.0 版中却没有。
允许的HTTP请求方式——装饰器
限定http请求方式
require_http_methods([Mthods_list])
- Mthods_list为请求方式列表,如:[‘GET’, ‘POST’]
require_GET()
- 只允许使用get方式进行请求
require_POST()
- 只允许使用post方式进行请求
require_safe()
- 只允许使用get方法和head方法的装饰器
Render
-
标准语法:
render(<request>, <template_name>, context=None, content_type=None, status=None, using=None)
-
必选参数
- request —— 生成HttpRequest对象
- template_name —— 指定需要渲染的模板名称
-
可选参数
- context —— 上下文,必须是一个字典。在HTML文件中使用字典的Key,通过Key展示对应的value
- content_type —— 指定上下文类型
- status —— 响应状态码
- using —— 用于加载模板的引擎名称
- Django templates language
- jinjia2
过滤器
first
- 返回列表list的第一个值
last
- 返回列表list的最后一个值
length
- 返回变量值的长度,可以用于字符串、列表
linebrakebr
- 将纯文本文件中的换行转换为HTML中的换行符
linenumbers
- 显示行号
ljust
- 左对齐
rjust
- 右对齐
lower
- 全部小写
upper
- 全部大写
title
- 将首字母全部大写
wordcount
- 统计单词的数量
mysql
# 检查是否安装mysql
ps -aux | grep 'mysql'
# 安装服务端
sudo apt-get install mysql-server
# 安装客户端
sudo apt-get install mysql-client
# 启动服务
sudo service mysql start
# 停止服务
sudo service mysql stop
# 重启服务
sudo service mysql restart
# 进入数据库
sudo mysql -uroot -p
- 取消mysql连接限制问题,否则每次进入数据库都需要在前面加上sudo
# 进入管理员模式
alexlu@alexlu-Ubuntu:~$ sudo su
# 进入MySQL
root@alexlu-Ubuntu:/home/alexlu# mysql
# 查看用户权限
mysql> select user,plugin from mysql.user;
# 更新root用户密码(此处密码设为‘root’)
mysql> update mysql.user set authentication_string=PASSWORD('root'),plugin='mysql_native_password';
# 刷新设置
mysql> flush privileges;
# 退出MySQL与root用户
mysql> exit;
root@alexlu-Ubuntu:/home/alexlu# exit
# 重启数据库服务
alexlu@alexlu-Ubuntu:~$ sudo service mysql restart
# 尝试重新登陆(前面不加sudo)
alexlu@alexlu-Ubuntu:~$ mysql -uroot -proot
数据库的创建与删除
# 展示当前数据库:
mysql> show databases;
# 创建数据库(django为数据库名称)-此处未设置中文编码
mysql> create database django;
# 查看创建的数据库
mysql> show create database django;
# 删除数据库
mysql> drop database django;
# 创建支持中文编码的数据库
mysql> create database django charset='utf8';
表的创建与删除
# 查看当前使用的数据库
mysql> select database();
# 选择使用的数据库
mysql> use django_AlexLu;
# 创建表
mysql> create table students(
-> id int primary key auto_increment not null,
-> name varchar(20),
-> age int default 20
-> );
# 显示创建的表
mysql> show create table students;
# 显示表结构
mysql> desc students;
# 显示已创建的表
mysql> show tables;
# 向表中插入数据
mysql> insert into students(name,age) values('Tom', 22);
# 查询表中的数据
mysql> select * from students;
Django连接MySQL
- 设置数据库连接项
# 在django的settings.py文件中对DATABASES进行设置
DATABASES = {
'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_AlexLu',
'USER': 'root',
'PASSWORD': 'root',
'HOST': 'localhost',
'PORT': 3306
}
}
- 安装pymysql
pip install pymysql
- 配置pymysql
# 在django项目下的__init__.py中进行设置
import pymysql
pymysql.install_as_MySQLdb()
- 可能会出现的错误
django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3.
- 解决办法
# 安装libmysqlclient-dev
sudo apt-get install libmysqlclient-dev
# 安装mysqlclient
pip install mysqlclient
# 修改django项目下的__init__.py(去掉上面第3步增加的两行内容)改为:
import MySQLdb
- 补充(mysql开发包的安装)
# Ubuntu
sudo apt-get install libmysqlclient-dev
# CentOS
yum install python-devel mysql-devel
MySQL数据库迁移
# 生成迁移文件
python manage.py makemigrations
# 将迁移文件映射到数据库中
python manage.py migrate
# 如需强制迁移需要在上方命令后面加上 应用名
ORM
- Object Relational Mapping
- ORM(类、对象、属性)——DB(数据表、数据行、字段)
流程说明
- 创建models
- 通过models创建迁移文件(makemigrations)
- 通过迁移文件映射到数据库中(migrate)
将数据库表格信息展示在django后台
# 在app下的admin.py中进行设置
from django.contrib import admin
from .models import Articles
admin.site.register(Articles)
设置django后台展示出表格更多的列
# 在app文件下的admin.py中进行设置
from django.contrib import admin
from .models import Articles
class AritclesAdmin(admin.ModelAdmin):
list_display = ['id', 'title', 'content', 'author']
admin.site.register(Articles, AritclesAdmin)
设置django后台表结构显示中文列名
# 修改app下的模型文件models.py,在字段创建时设置中文名称
class Articles(models.Model):
title = models.CharField('标题', max_length=20)
author = models.CharField('作者', max_length=20)
content = models.TextField('内容')
- 设置完成后需要重新对数据库进行迁移
数据库表格列字段设置为选项(性别为可选项)
class Students(models.Model):
choices = [
('male', '男'),
('female', '女')
]
name = models.CharField(verbose_name='姓名', max_length=20, unique=True)
age = models.CharField(verbose_name='年龄', max_length=10)
gender = models.CharField(verbose_name='性别', max_length=10, choices=choices, default='male')
is_deleted = models.BooleanField(default=False)
introduce = models.TextField(verbose_name='自我介绍')
模型中的元数据(Meta)
设置django后台表名显示为中文
# 在app下的模型文件models.py中进行设置
class Articles(models.Model):
title = models.CharField('标题', max_length=20)
author = models.CharField('作者', max_length=20)
content = models.TextField('内容')
def __str__(self):
return self.title
class Meta:
verbose_name_plural = '新闻列表'
verbose_name = '新闻'
- 在表格模型定义中增加子类Meta,通过verbose_name_plural与verbose_name设置中文名称即可
设置django后台表结构列名的排序方式
# 在模型定义下的Meta子类中增加ordering字段进行设置
class Meta:
verbose_name_plural = '用户列表'
verbose_name = '用户'
ordering = ['age', '-name']
# ordering = ['-id']
修改表格名称
# 同样是在Mate子类中增加db_table字段进行设置
class Meta:
verbose_name_plural = '用户列表'
verbose_name = '用户'
ordering = ['age', '-name']
db_table = 'students'
数据查询(从数据库中获取数据)
流程
- Model(database) → QuerySet(views → context) → html(templates)
查询表中全部数据
# 在视图views定义中,通过context传递给需要渲染的html
from django.shortcuts import render
from .models import Students
# Create your views here.
def index(request):
student_list = Students.objects.all() # 此处为获取表中所有数据
context = {
'students': student_list
}
return render(request, 'index.html', context)
# 在模板templates下的index.html中进行展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for student in students %}
<h1>{{ student.name }}——{{ student.age }}</h1>
{% endfor %}
</body>
</html>
- 需要配置好urls,此处忽略配置urls的内容,需要根据实际情况自行设置
查询表中某一条数据
# 在视图views定义中,通过context传递给需要渲染的html
from django.shortcuts import render
from .models import Magnate
# Create your views here.
def index(request):
context = {
'result': Magnate.objects.get(pk=1) # 此处查询的值必须是唯一的
}
return render(request, 'index.html', context)
# 在模板templates下的index.html中进行展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{ result.name }}</h1>
<h1>{{ result.age }}</h1>
<h1>{{ result.gender }}</h1>
<h1>{{ result.assets }}</h1>
<h1>{{ result.company }}</h1>
</body>
</html>
查询表中多条数据(过滤条件的使用)
# 在视图views定义中,通过context传递给需要渲染的html
from django.shortcuts import render
from .models import Magnate
# Create your views here.
def index(request):
context = {
'female_list': Magnate.objects.filter(gender='female')
# 'male_list': Magnate.objects.exclude(gender='female')
}
return render(request, 'index.html', context)
# 在模板templates下的index.html中进行展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for female in female_list %}
<h1>{{ female.name }}——{{ female.assets }}</h1>
{% endfor %}
</body>
</html>
- filter —— 查询结果为满足条件的记录
- exclude —— 查询结果为不满足条件的记录
二次查询(多次查询)
# 在视图views定义中,通过context传递给需要渲染的html
from django.shortcuts import render
from .models import Magnate
# Create your views here.
def index(request):
magnates = Magnate.objects.all().filter(gender='male').filter(assets=2125)
context = {
'male_list': magnates
}
return render(request, 'index.html', context)
# 在模板templates下的index.html中进行展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for male in male_list %}
<h1>{{ male.name }}——{{ male.assets }}</h1>
{% endfor %}
</body>
</html>
查询后排序
# 在视图views定义中,通过context传递给需要渲染的html
from django.shortcuts import render
from .models import Magnate
# Create your views here.
def index(request):
magnates = Magnate.objects.filter(gender='male').order_by('-age')
context = {
'magnates': magnates
}
return render(request, 'index.html', context)
# 在模板templates下的index.html中进行展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for magnate in magnates %}
<h1>{{ magnate.name }}——{{ magnate.gender }}——{{ magnate.age }}</h1>
{% endfor %}
</body>
</html>
通过某个字段进行查询
# 在视图views定义中,通过context传递给需要渲染的html
from django.shortcuts import render
from .models import Magnate
# Create your views here.
def index(request):
magnates = Magnate.objects.values('name', 'assets')
context = {
'magnates': magnates
}
return render(request, 'index.html', context)
# 在模板templates下的index.html中进行展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for magnate in magnates %}
<h1>{{ magnate.name }}——{{ magnate.gender }}——{{ magnate.age }}</h1>
{% endfor %}
</body>
</html>
- 此处界面不会显示性别信息,因为在视图中查询时只设置了姓名与资产两个字段
- values() 后括号为空时,查询所有字段,等价于 all()
- values与all的区别为,前者以字典形式返回,后者以对象形式返回
模糊查询
以xxx开头或以xxx结尾
# views视图中filter括号中使用模糊匹配的字段即可
magnates = Magnate.objects.filter(company__startswith='阿里')
- 字段名__startswith:以xxx开头,对大小写敏感
- 字段名__isstartswith:以xxx开头
- 字段名__endswith:以xxx结尾,对大小写敏感
- 字段名__isendswith:以xxx结尾
in查询
# views视图中filter括号中使用 字段名__in 即可
results = Magnate.objects.filter(age__in=[45, 58, 50])
范围查询
# views视图中filter括号中使用范围查询的字段即可
results = Magnate.objects.filter(age__range=(20, 45))
- 范围查询使用元组用来表示范围,只适用于数值型字段
判断条件查询
# views视图中filter括号中使用条件判断的字段即可
results = Magnate.objects.filter(assets__gt=1000)
- 字段名__gt:大于
- 字段名__gte:大于等于
- 字段名__lt:小于
- 字段名__lte:小于等于
向数据库中插入数据
# 在视图views定义中,通过create设置需要插入的数据
Magnate.objects.create(name='AlexLu', age=50, gender='male', assets=666, company='创慧弘', introduce='CHH Co., Ltd.')
数据统计
# 在视图views定义中,通过count进行统计
from django.shortcuts import render
from .models import Magnate
# Create your views here.
def index(request):
magnates = Magnate.objects.filter(gender='male').count()
context = {
'count': magnates
}
return render(request, 'index.html', context)
# 在模板templates下的index.html中进行展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{ count }}</h1>
</body>
</html>
Count - Sum - Avg - Max - Min
# 需要在视图中导入相关统计函数
from django.db.models import Count, Sum, Avg, Max, Min
# 在视图中统计时通过aggregate进行调用
results = Magnate.objects.aggregate(Count('name'), Sum('assets'), Avg('assets'), Max('assets'), Min('assets'))
- 返回值为字典形式:
{'name__count': 10, 'assets__sum': 14446, 'assets__avg': 1444.6, 'assets__max': 2387, 'assets__min': 400}
- 也可通过filter过滤后调用对应的统计函数实现
表单
1. 创建表单
# 在应用下创建forms.py
from django import forms
class RegisterForms(forms.Form):
user_name = forms.CharField(min_length=8, max_length=20, label='用户名', initial='请输入您的手机号/密码')
password = forms.CharField(widget=forms.PasswordInput, min_length=8, max_length=16, label='密码', help_text='密码为8-16位数字字母组合')
repassword = forms.CharField(widget=forms.PasswordInput, min_length=8, max_length=16, label='确认密码')
age = forms.IntegerField(min_value=18, max_value=100, label='年龄')
# age = forms.Field(widget=forms.NumberInput, label='年龄')
email = forms.EmailField(label='邮箱', disabled=True)
phone = forms.CharField(max_length=11, label='手机号码', label_suffix=':(+86)')
introduce = forms.CharField(label='自我介绍', widget=forms.Textarea)
2. 创建表单视图(将表单传递到前端页面)
# 在应用下的views.py中进行创建
from django.shortcuts import render
from .forms import RegisterForms
from django.views import View
class IndexForms(View):
def get(self, request):
forms = RegisterForms()
return render(request, 'index.html', {'forms': forms})
3. 配置路由
# 在应用下的urls.py中进行配置
urlpatterns = [
path('', views.IndexForms.as_view(), name='form'),
]
4. 编写前端页面代码
{# 在应用下templates中创建index.html进行编写 #}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
<table>
{{ forms.as_table }} {#渲染成表格#}
<tr>
<td><input type="submit" value="确认登陆" name="submit"></td>
</tr>
</table>
</form>
<hr>
<form action="" method="post">
<div>
{{ forms.as_p }} {#渲染成段落#}
<td><input type="submit" value="确认登陆" name="submit"></td>
</div>
</form>
<hr>
<form action="" method="post">
<div>
{{ forms.as_ul }} {#渲染成标签#}
<td><input type="submit" value="确认登陆" name="submit"></td>
</div>
</form>
</body>
</html>
5. 前端界面美化(增加CSS样式)
方法一
{# 直接在index.html文件中增加样式 #}
{# 在<head>标签中增加<style>标签设置相应控件的样式 #}
<style>
#id_username{
border-radius: 5px;
}
</style>
方法二
# 在表单文件forms.py中为控件绑定样式类
from django import forms
class RegisterForms(forms.Form):
username = forms.CharField(min_length=8, max_length=20, label='用户名', initial='请输入您的手机号/密码', widget=forms.TextInput(attrs={'class': 'custom-forms'}))
password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='密码', help_text='密码为8-16位数字字母组合')
repassword = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='确认密码')
age = forms.IntegerField(min_value=18, max_value=100, label='年龄', widget=forms.TextInput(attrs={'class': 'custom-forms'}))
# age = forms.Field(widget=forms.NumberInput, label='年龄')
email = forms.EmailField(label='邮箱', disabled=True, widget=forms.TextInput(attrs={'class': 'custom-forms'}))
phone = forms.CharField(max_length=11, label='手机号码', label_suffix=':(+86)', widget=forms.TextInput(attrs={'class': 'custom-forms'}))
introduce = forms.CharField(label='自我介绍', widget=forms.Textarea(attrs={'class': 'custom-forms-textarea'}))
{# 在<head>标签中增加<style>标签设置控件对应样式类的属性 #}
<style>
.custom-forms{
border-radius: 5px;
}
.custom-forms-textarea{
border-radius: 15px;
}
</style>
6. 选择控件
# 直接在表单文件form.py中定义控件时设置
from django import forms
class RegisterForms(forms.Form):
choices_item = [
(1, '男'), (2, '女'), (3, '保密')
]
# 下拉列表
gender = forms.ChoiceField(label='性别', choices=choices_item, nitial=3)
# 单选
gender2 = forms.ChoiceField(label='性别', choices=choices_item, widget=forms.RadioSelect, initial=2)
# 复选
gender3 = forms.MultipleChoiceField(label='性别', choices=choices_item, widget=forms.CheckboxSelectMultiple, initial=1)
7. 日期控件
from django import forms
class RegisterForms(forms.Form):
formats = [
'%Y-%m-%d', # '2019-6-30'
'%m/%d/%Y', # '06/30/2019'
'%m/%d/%y', # '06/30/19'
]
# 日期输入框
birthday = forms.DateField(label='出生日期', input_formats=formats)
year_list = [
1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
]
# 日期选择框
birthday2 = forms.DateField(label='出生日期', input_formats=formats, widget=forms.SelectDateWidget(years=year_list))
日期控件数据验证
# 在应用下的views.py中的控件类视图中通过forms.is_valid()进行验证
from django.shortcuts import render, HttpResponse
from .forms import RegisterForms
from django.views import View
class IndexForms(View):
def get(self, request):
forms = RegisterForms()
return render(request, 'index.html', {'forms': forms})
def post(self, request):
forms = RegisterForms(request.POST)
if forms.is_valid():
birthday = forms.cleaned_data.get('birthday')
return render(request, 'home.html', {'birthday': birthday})
else:
return HttpResponse('<h1>对不起,您输入的出生日期有误~!</h1>')
{# 可通过home.html获取数据并展示 #}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎登陆Django后台管理系统</title>
</head>
<body>
<h1>{{ birthday }}</h1>
</body>
</html>
8. 获取表单数据
# django项目的应用下的forms.py
from django import forms
class RegisterForms(forms.Form):
choices_item = [
(1, '男'), (2, '女'), (3, '保密')
]
hobbies = [
(1, '足球'), (2, '篮球'), (3, 'Python')
]
year_list = [
1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
]
username = forms.CharField(min_length=8, max_length=20, label='用户名', initial='请输入您的手机号/密码', widget=forms.TextInput(attrs={'class': 'custom-forms'}))
password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='密码', help_text='密码为8-16位数字字母组合')
repassword = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='确认密码')
gender = forms.ChoiceField(label='性别', choices=choices_item, nitial=3)
age = forms.IntegerField(min_value=18, max_value=100, label='年龄', widget=forms.NumberInput(attrs={'class': 'custom-forms'}))
birthday = forms.DateField(required=False, label='出生日期', widget=forms.SelectDateWidget(years=year_list))
hobby = forms.MultipleChoiceField(label='爱好', choices=hobbies, widget=forms.CheckboxSelectMultiple)
introduce = forms.CharField(label='自我介绍', widget=forms.Textarea(attrs={'class': 'custom-forms-textarea'}))
# 应用下的视图文件views.py中编写表单对应的类视图
from django.shortcuts import render, HttpResponse
from .forms import RegisterForms
from django.views import View
class IndexForms(View):
def get(self, request):
forms = RegisterForms()
return render(request, 'index.html', {'forms': forms})
def post(self, request):
forms = RegisterForms(request.POST)
if forms.is_valid():
username = forms.cleaned_data.get('username')
password = forms.cleaned_data['password']
context = {
# 以字典形式处理表单数据
'datalist': {
'username': username,
'password': password,
'repassword': repassword,
'age': age,
'gender': gender,
'birthday': birthday,
'hobby': hobby,
'introduce': introduce,
},
# 以列表形式处理表单数据
'datalist2': [
username,
password,
repassword,
age,
gender,
birthday,
hobby,
introduce,
],
}
return render(request, 'home.html', context=context)
else:
return HttpResponse('<h1>对不起,您输入的信息有误~!</h1>')
{# 通过home.html接收表单数据并展示 #}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎登陆Django后台管理系统</title>
</head>
<body>
{#接收字典形式数据#}
{% for k, v in datalist.items %}
<h1>{{ k }}---{{ v }}</h1>
{% endfor %}
<hr>
{#接收列表形式数据#}
{% for field in datalist2 %}
<h1>{{ field }}</h1>
{% endfor %}
</body>
</html>
模型表单(ModelForm)
1. 在模型文件models.py中设置好数据库映射
from django.db import models
class Magnate(models.Model):
choices = [
('male', '男'),
('female', '女')
]
name = models.CharField(verbose_name='姓名', max_length=20, unique=True)
age = models.CharField(verbose_name='年龄', max_length=10)
gender = models.CharField(verbose_name='性别', max_length=10, choices=choices, default='male')
assets = models.IntegerField(verbose_name='资产')
company = models.CharField(verbose_name='公司', max_length=50)
is_deleted = models.BooleanField(default=False)
introduce = models.TextField(verbose_name='介绍')
class Meta:
verbose_name_plural = '富豪榜'
verbose_name = '富豪'
ordering = ['id']
2. 建立模型表单
# 在应用下的forms.py中进行建立
from django import forms
from .models import Magnate
class MagnatesForms(forms.ModelForm):
class Meta:
model = Magnate
# 获取全部字段
# fields = '__all__'
# 指定过滤掉字段‘isdeleted’
# exclude = ['is_deleted']
# 指定获取的字段列表
fields = ['name', 'age', 'assets', 'company']
3. 创建模型表单对应的视图
# 在应用下的views.py中进行创建
from django.shortcuts import render, HttpResponse
from .models import Magnate
from .forms import MagnatesForms
from django.views import View
class IndexMagnate(View):
def get(self, request):
forms = MagnatesForms()
return render(request, 'index.html', {'forms': forms})
4. 前端页面展示模型表单
{# 在应用中templates下的index.html进行展示 #}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.custom-forms{
border-radius: 5px;
}
.custom-forms-textarea{
border-radius: 15px;
}
</style>
</head>
<body>
<form action="" method="post">
<div>
{{ forms.as_p }} {#渲染成段落#}
<td><input type="submit" value="确认登陆" name="submit"></td>
</div>
</form>
</body>
</html>
5. 为模型表单页面配置路由
# 在项目的路由文件urls.py中通过include关联到应用路由
from django.contrib import admin
from django.urls import path, include
from news import urls as news_urls
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(news_urls)),
]
# 在应用下的路由文件urls.py中将创建的模型表单视图与路径进行匹配
from django.urls import path
from news import views
urlpatterns = [
path('', views.IndexMagnate.as_view(), name='magnate'),
]
为模型表单增加字段
# 直接在forms.py中的模型表单定义中增加
# 此处增加了password与repassword两个字段
from django import forms
from .models import Magnate
class MagnatesForms(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='密码', help_text='密码为8-16位数字字母组合')
repassword = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='确认密码')
class Meta:
model = Magnate
# 获取全部字段
# fields = '__all__'
# 指定过滤掉字段‘isdeleted’
# exclude = ['is_deleted']
# 指定获取的字段列表————可用来调整显示顺序
fields = ['name', 'gender', 'age', 'password', 'repassword', 'assets', 'company']
为模型表单渲染CSS样式
# 直接在forms.py中的模型表单定义下增加widgets通过字典为相应的字段绑定控件及CSS样式
from django import forms
from .models import Magnate
class MagnatesForms(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='密码', help_text='密码为8-16位数字字母组合')
repassword = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='确认密码')
class Meta:
model = Magnate
# 获取全部字段
# fields = '__all__'
# 指定过滤掉字段‘isdeleted’
# exclude = ['is_deleted']
# 指定获取的字段列表————可用来调整显示顺序
fields = ['name', 'gender', 'age', 'password', 'repassword', 'assets', 'company']
widgets = {
'name': forms.TextInput(attrs={'class': 'custom-textinput'}),
'introduce': forms.Textarea(attrs={'class': 'custom-textinput', 'row': 30, 'cols': 80}),
}
{# 在html中为控件设定CSS样式 #}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.custom-forms{
border-radius: 5px;
}
.custom-forms-textarea{
border-radius: 15px;
}
.custom-textinput{
border: 5px solid #00ff00;
border-radius: 5px;
}
</style>
</head>
<body>
<form action="" method="post">
<div>
{{ forms.as_p }} {#渲染成段落#}
<td><input type="submit" value="确认登陆" name="submit"></td>
</div>
</form>
</body>
</html>
表单的手动渲染
普通表单的手动渲染
# 利用前端知识在html中直接进行样式设置
<form action="" method="post">
<hr>
<ul>
<li style="list-style-type: none;">
<span style="color: #ff0000">
{{ forms.username.label }} :
</span>
<span>
{{ forms.username }}
</span>
<span style="margin-left: 10px">
{{ forms.username.help_text }}
</span>
</li>
</ul>
<hr>
<td><input type="submit" value="确认登陆" name="submit"></td>
</form>
模型表单的手动渲染
# 直接在模型表单定义中增加前端需要界面展示的信息,并在html中进行渲染
from django import forms
from .models import Magnate
class MagnatesForms(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='密码', help_text='密码为8-16位数字字母组合')
repassword = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'custom-forms'}), min_length=8, max_length=16, label='确认密码')
class Meta:
model = Magnate
# 获取全部字段
# fields = '__all__'
# 指定过滤掉字段‘isdeleted’
# exclude = ['is_deleted']
# 指定获取的字段列表————可用来调整显示顺序
fields = ['name', 'gender', 'age', 'password', 'repassword', 'assets', 'company']
widgets = {
'name': forms.TextInput(attrs={'class': 'custom-textinput'}),
'introduce': forms.Textarea(attrs={'class': 'custom-textinput', 'row': 30, 'cols': 80}),
}
help_texts = {
'name': '请输入中文姓名全称',
}
labels = {
'name': '中文姓名',
}
模型表单的数据保存(MySQL)
# 连接好MySQL数据库,在模型表单视图中post方法内进行数据获取和保存
from django.shortcuts import render, HttpResponse
from .models import Magnate
from .forms import MagnatesForms
from django.views import View
class IndexMagnate(View):
def get(self, request):
forms = MagnatesForms()
return render(request, 'index.html', {'forms': forms})
def post(self, request):
forms = MagnatesForms(request.POST)
if forms.is_valid():
forms.save()
return HttpResponse('<h1>数据保存成功!</h1>')
else:
return HttpResponse('<h1>数据保存失败!</h1>')
未完待续
以上学习笔记是根据视频教程 Python之Django企业开发实战 的思路进行初步整理,待内容完整后进行重新梳理。
最后感谢陈老师详细的教学视频。
你只管努力就好,最坏的结果也不过是大器晚成。