当前位置: 移动技术网 > IT编程>脚本编程>Python > Django学习笔记

Django学习笔记

2019年08月22日  | 移动技术网IT编程  | 我要评论

闵孝林,幽默笑话小故事,下载电影的网址

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

  1. 设置数据库连接项
# 在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
    }
}
  1. 安装pymysql
pip install pymysql
  1. 配置pymysql
# 在django项目下的__init__.py中进行设置
import pymysql
pymysql.install_as_mysqldb()
  1. 可能会出现的错误
django.core.exceptions.improperlyconfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3.
  1. 解决办法
# 安装libmysqlclient-dev
sudo apt-get install libmysqlclient-dev
# 安装mysqlclient
pip install mysqlclient
# 修改django项目下的__init__.py(去掉上面第3步增加的两行内容)改为:
import mysqldb
  1. 补充(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(数据表、数据行、字段)

流程说明

  1. 创建models
  2. 通过models创建迁移文件(makemigrations)
  3. 通过迁移文件映射到数据库中(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, '', context)
# 在模板templates下的中进行展示
<!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, '', context)
# 在模板templates下的中进行展示
<!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, '', context)
# 在模板templates下的中进行展示
<!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, '', context)
# 在模板templates下的中进行展示
<!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, '', context)
# 在模板templates下的中进行展示
<!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, '', context)
# 在模板templates下的中进行展示
<!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, '', context)
# 在模板templates下的中进行展示
<!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, '', {'forms': forms})

3. 配置路由

# 在应用下的urls.py中进行配置
urlpatterns = [
    path('', views.indexforms.as_view(), name='form'),
]

4. 编写前端页面代码

{# 在应用下templates中创建进行编写 #}
<!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样式)

方法一

{# 直接在文件中增加样式 #}
{# 在<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, '', {'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, '', {'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, '', {'forms': forms})

4. 前端页面展示模型表单

{# 在应用中templates下的进行展示 #}
<!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, '', {'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企业开发实战 的思路进行初步整理,待内容完整后进行重新梳理。

最后感谢陈老师详细的教学视频。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网