Python之Django框架(一)



引入

Web框架是帮助服务器处理动态请求的应用程序。

服务器接收到http请求报文后,首先判断它请求的资源是静态资源还是动态资源。如果是静态资源,服务器就直接组合响应报文返回对应资源。

如果是动态资源,服务器就将http请求报文打包成WSGI协议格式的数据,转交给Web框架。

Web框架得到请求路径等信息,自动路由到对应处理函数,组装静态文件和数据,返回给服务器。

服务器得到处理后的数据,组装响应报文,返回给请求方。

总而言之,web框架的基本功能:

  • 接收数据
  • 处理数据
  • 返回数据

前人已经搭建了许许多多的web框架,它们都能自动实现以上流程,使得程序员们不再需要关心具体细节,而是更多地去关注处理逻辑。


Django简介

Django,发音为[`dʒæŋɡəʊ],是用python语言写的开源web开发框架,并遵循MVC设计。

劳伦斯出版集团为了开发以新闻内容为主的网站,而开发出来了这个框架,于2005年7月在BSD许可证下发布。如今,Django框架已经能够胜任处理大部分Web应用程序的任务了。

Django被设计出来的主要目的是简便、快速地开发数据库驱动的网站。

特点

Django是一个重量级框架,它能支持大量的操作,内容丰富:

  • 提供项目工程管理的自动化脚本工具
  • 数据库ORM支持(对象关系映射,英语:Object Relational Mapping)
  • 模板
  • 表单
  • Admin管理站点
  • 文件管理
  • 认证权限
  • session机制
  • 缓存
MVC设计

MVC设计模式的核心思想是分工、解耦,让不同的代码块之间降低耦合,增强代码的可扩展性和可移植性,实现向后兼容。

M:Model-----模型

指从现实世界中抽象出来的对象模型,是应用逻辑的反应;它封装了数据和对数据的操作,是实际进行数据处理的地方(模型层与数据库才有交互)。主要负责数据处理

V:Viem-----视图

是应用和用户之间的接口,它负责将应用显示给用户 和 显示模型的状态。主要负责页面显示

C:Controller------控制器

控制器负责视图和模型之间的交互,控制对用户输入的响应、响应方式和流程;它主要负责两方面的动作,一是把用户的请求分发到相应的模型,二是吧模型的改变及时地反映到视图上。主要负责过程控制

在Web开发中,

  • Model主要封装对数据库层的访问,对数据库中的数据进行增、删、改、查操作。

  • View用于封装结果,生成页面展示的html内容。

  • Controller用于接收请求,处理业务逻辑,与Model和View交互,返回结果。

Django MVT设计

Django的MVT设计是MVC设计的变形

  • M,Model,模型,与MVC中的M功能相同,负责和数据库交互,进行数据处理。
  • V,View,视图,与MVC中的C功能相同,接收请求,进行业务处理,返回应答。
  • T,Template,模板,与MVC中的V功能相同,负责封装构造要返回的html。

虚拟环境

环境指的是程序编写和运行所依赖的解释器和库文件。

一般,Python程序的运行环境是全局环境。即所有Python程序都使用同一个环境。

这样会产生很多问题:

各个程序所需要的解释器、包或模块的版本号不同怎么办?

除了重复安装卸载外,搭建虚拟环境是一个很好的解决办法。

虚拟环境指的是给项目创建一个"与世隔绝"的运行环境。这样,各个项目的运行环境就能够互不干扰。

搭建方法
Linux
#安装所需要的模块
sudo pip install virtualenv
sudo pip install virtualenvwrapper

#创建虚拟环境保存地
mkdir $HOME/.virtualenvs

# 打开~/.bashrc文件,添加环境变量:
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh

#激活环境变量
source ~/.bashrc

#创建虚拟环境(解释器和pip);创建完默认直接进入
mkvirtualenv -p python3 env_name

#进入虚拟环境后安装指定版本包或模块
pip install django==1.11.11

#查看所有虚拟环境
workon

#使用虚拟环境env_name
workon env_name

#退出虚拟环境
deactivate

#删除虚拟环境env_name
rmvirtualenv env_name
Windows
#安装所需要的模块
pip install virtualenv
pip install virtualenvwrapper

#创建一个文件夹保存虚拟环境
mkdir my_virtualenvs

#创建虚拟环境(解释器和pip)
virtualenv env_name

#启动虚拟环境
env_name\scripts\activate

#进入虚拟环境后会出现小括号
(env_name): pip install django==1.11.11

#退出虚拟环境
deactivate

Django项目

创建项目
django-admin startproject project_name
  • 创建项目project_name

创建成功后,项目结构如下:

在这里插入图片描述

  • manage.py :一个能进行各种操作的脚本

  • asgi.py:ASGI配置文件,即异步的(Async)WSGI

  • setting.py:项目总的配置文件

  • urls.py:URL匹配相关配置文件

  • wsgi.py:WSGI配置文件

运行调试服务器
python manage.py runserver ip:port
#默认为localhost:8000
python manage.py runserver

打开浏览器输入对应ip地址和端口号即可实时查看页面效果

Ctrl C停止运行

子应用

子应用是一个个功能独立的模块。如:登录、注册、支付…

创建子应用,不仅可以保持模块间的独立,而且还方便以后的项目复用。

python manage.py startapp sub_app
  • 创建子应用sub_app

python manage.py startapp lookup

创建成功后,子应用结构:

在这里插入图片描述

  • admin.py:与网站的后台管理相关
  • apps.py:当前子应用的相关配置
  • migrations:存放数据库迁移历史文件
  • models.py:数据模型相关
  • tests.py:开发测试相关
  • views.py:动态清楚处理的视图相关
子应用注册

子应用只有安装注册后才能被项目使用。

注册安装子应用只需在settings.py中的INSTALLED_APPS列表内添加新的子应用的apps.py文件中xxxConfig类。

如子应用名是lookup,就应该添加lookuo.apps.LookupConfig类(这个类系统自动生成)

在这里插入图片描述

子应用设置

子应用创建之后,在app.py中会自动生成xxxConfig类:

from django.apps import AppConfig


class LookupConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'lookup'

我们可以在这里添加一些其他的设置。

比如,verbose_name,是子应用在后台上显示的名字。

from django.apps import AppConfig


class LookupConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'lookup'
    verbose_name="书籍与作者查询"

模型Models

子应用的models.py负责与数据库进行交互

数据库设置

在项目的settings.py文件中,可以修改数据库相关设置。

Django默认使用splite数据库:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

可以修改为其他数据库,如MySQL.

首先安装所需模块:

pip install pymysql

其次在与项目文件夹同名的子文件夹中的__init__文件中添加导入安装语句

import pymysql

pymysql.install_as_MySQLdb()

最后修改settings.py文件中的数据库配置:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',  # mysql引擎
        'HOST': '127.0.0.1',  # 数据库主机地址
        'PORT': 3306,  # 数据库端口
        'USER': 'root',  # 数据库用户名
        'PASSWORD': '123',  # 数据库用户密码
        'NAME': 'library_system'  # 数据库名字
    }
}
ORM模式

Django将与数据库交互的各种操作封装成了ORM模式。

即对象关系映射(Object Relational Mapping,简称ORM)模式

数据表----------->模型类

数据行----------->对象/实例

字段 -------------->属性

即,程序员通过ORM模式进行逻辑层次的面向对象的编程,Django框架负责自动把这些操作转化为sql语句,并与对应数据库(可能种类不同)交互。

这样的话,程序员就不用关心底层细节,实现了数据库操作的抽象化与简单化。

数据库迁移
设计表-----定义模型类

在子应用的models.py中可以定义子应用需要用到的模型类。[模型类 → \rightarrow 数据表]

  • 这些模型类都需继承自models.Model

创建字段就是在类中创建属性。[模型类属性 → \rightarrow 数据表字段]

  • 这些属性的创建需要用到models中的API类。一般格式为类型大写+Filed,如CharFiled
类名说明
AutoField自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性
BooleanField布尔字段,值为True或False
NullBooleanField支持Null、True、False三种值
CharField字符串,参数max_length表示最大字符个数
TextField大文本字段,一般超过4000个字符时使用
IntegerField整数
DecimalField十进制浮点数, 参数max_digits表示总位数, 参数decimal_places表示小数位数
FloatField浮点数
DateField日期, 参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为False; 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为False; 参数auto_now_add和auto_now是相互排斥的,组合将会发生错误
TimeField时间,参数同DateField
DateTimeField日期时间,参数同DateField
FileField上传文件字段
ImageField继承于FileField,对上传的内容进行校验,确保是有效的图片
  • 创建字段属性时,还可以添加一些选项和限制:
选项说明
null如果为True,表示允许为空,默认值是False
blank如果为True,则该字段允许为空白,默认值是False
db_column字段的名称,如果未指定,则使用属性的名称
db_index若值为True, 则在表中会为此字段创建索引,默认值是False
default默认值
primary_key若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用
unique如果为True, 这个字段在表中必须有唯一值,默认值是False
verbose_name用于在后台等地方显示,便于读懂和操作
  • 设置外键通过models.ForeignKey(),第一个参数是外键关联到的表的字段,还可以传入on_delete属性规定主表数据删除后外键表的行为:
on_delete可选值行为
models.CASCADE级联,删除主表数据时连同外键表中数据一起删除
models.PROTECT保护,通过抛出ProtectedError异常,来阻止删除主表中被外键应用的数据
models.SET_NULL设置为NULL,仅在该字段null=True允许为null时可用
models.SET_DEFAULT设置为默认值,仅在该字段设置了默认值时可用
models.SET(…)设置为特定值或者调用特定方法
models.DO_NOTHING不做任何操作,如果数据库前置指明级联性,此选项会抛出IntegrityError异常
  • 还可以在模型类中重写Meta类和__str_,以实现某些小功能(详见官方文档)

下面以图书管理系统为例:

from django.db import models


# Create your models here.
class Writers(models.Model):
    """定义作者模型----作者表"""
    id = models.AutoField(verbose_name="作家编号", primary_key=True)
    name = models.CharField(max_length=30, verbose_name="姓名")
    birth = models.DateField(verbose_name="出生日期")
    country = models.CharField(max_length=20, verbose_name="国家")
    introduction = models.CharField(max_length=300,verbose_name="简介")

    class Meta:
        """元数据"""
        db_table = "writers_info"  # 迁移后建立的数据表名称
        verbose_name = "作家"  # 后台显示的名称

    def __str__(self):
        """数据项显示的内容"""
        return f"{self.name}  {self.country}"


class Books(models.Model):
    """定义书籍模型----书籍表"""
    id = models.AutoField(verbose_name="书籍编号", primary_key=True)
    name = models.CharField(max_length=20, verbose_name="名称")
    price = models.DecimalField(decimal_places=2,max_digits=5,verbose_name="价格")
    writer = models.ForeignKey(Writers, on_delete=models.CASCADE,verbose_name="作者编号")
    out_time = models.DateField(verbose_name="出版时间")
    introduction = models.CharField(max_length=300,verbose_name="简介")

    class Meta:
        """元数据"""
        db_table = "books_info"  # 迁移后建立的数据表名称
        verbose_name = "书籍"  # 后台显示的名称

    def __str__(self):
        """数据项显示的内容"""
        return f"{self.name}  {self.writer.name}"

生成表----模型类迁移转化到具体数据库中

定义好模型类后,在终端中进行迁移的操作:

#生成迁移文件-----xxxx_initial.py
python manage.py makemigrations

#迁移----同步数据库
python manage.py migrate

Django框架会在迁移文件中准备好一切关于数据库的配置,迁移之后,模型类就会在配置好的数据库中真正地变成数据表。

如下图,在数据库中自动创建了包括book_info和writers_info在内的一系列表

在这里插入图片描述


Admin站点管理

修改本地化配置

settings.py中可以修改网站的时区和语言

默认:

# Internationalization
# https://docs.djangoproject.com/en/4.0/topics/i18n/

LANGUAGE_CODE = 'en-us'   #英语

TIME_ZONE = 'UTC'   #世界协调时间

可以修改为:

LANGUAGE_CODE = 'zh-Hans'  #汉字

TIME_ZONE = 'Asia/Shanghai'   #上海时区
创建管理员
python manage.py createsuperuser
  • 按照提示输入用户名,邮箱,密码即可

重置密码:

python manager.py changepassword username
模型类注册

需要在子应用的admin.py文件导入模型类并注册,我们才能够在后台进行相关模型的数据库操作

from django.contrib import admin

# Register your models here.
from lookup.models import Books,Writers

admin.site.register(Books)
admin.site.register(Writers)
登录站点

启动服务器,登录http://ip:port/admin。如:http://127.0.0.1:8000/admin

在这里插入图片描述

在此进行的数据库操作会保存更新。

在这里插入图片描述


视图与URL

视图函数

视图是一个处理用户请求的函数。这个函数需要在views.py中定义。

视图函数的第一个参数预留给HttpRequest类的对象reqeustrequest在调用时包含用户的各种请求信息。

视图函数的返回值需要是一个HttpResponse类的对象。故需要导入HttpResponse模块 :

from django.http import HttpResponse

视图函数的内部由业务逻辑决定。一般要通过模型访问数据库得到数据,并替换模板html文件中预设的变量,组合成动态网页返回。

如简简单单的返回一句话:

# Create your views here.
def books_info(request):
    """书籍挑选页面"""
    return HttpResponse("Here are all the books.")


def student_info(request):
    """作家简介页面"""
    return HttpResponse("Here are all the writers.")
配置URL匹配路由

用户的请求URL(去掉ip,port,和请求参数)是一步一步与我们自己设置的URL匹配的。

首先是所有URL匹配机制的源头-----项目同名文件夹中的settings.py默认的有这么一行。

指明了匹配的第一步

ROOT_URLCONF = 'LibrarySystem.urls'   #URL设置

匹配的的第一步,就是项目相同文件夹中的urls.py中的urlpatterns列表

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

默认的这一行代码的意思是:如果请求URL以admin/开头,继续进入admin.site.urls中进行匹配。

实际上,我们的admin站点的那些网页的url就默认生成在admin.site.urls中。

我们可以在这个列表中添加path(正则表达式模式字符串,include(子应用.urls) )来将URL匹配引向子应用。(需要导入include;需要在子应用文件夹中创建urls.py)

如:

from django.contrib import admin
from django.urls import path
from django.conf.urls import include

urlpatterns = [
    path('admin/', admin.site.urls),  #依次往下
    path('lookup/',include('lookup.urls'))   #以lookup开头就导向lookup.urls中的urlpatterns
]

经过主文件夹的引流,匹配的阵地转移到子应用文件夹中我们创建的urls.py.

from django.urls import path
from lookup.views import books_info,writers_info

urlpatterns = [
    path('books/', books_info),  #匹配/lookup/books/,交给books_info视图函数处理
    path('writers/', writers_info)  #匹配/lookup/writers/,交给writers_info处理
]

在这里插入图片描述

在这里插入图片描述


静态文件与模板文件

我们把所有静态文件和模板分别放至新创建的文件夹staic,templates

在这里插入图片描述

静态文件配置

settings.py中修改设置以下两个值

import os

# 静态文件url
STATIC_URL = '/static/'

# 静态文件目录
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]
  • 这样就可以通过http://ip:port/static/...来访问static目录中的静态文件了
动态模板文件配置

settings.py中修改设置’DIR’项为模板文件目录

import os

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS':[os.path.join(BASE_DIR, 'templates')],   #修改模板文件目录
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
编写模板文件

模板文件大部分是需要进行数据替换的html文件。

我们可以使用以下语法在html文件中中添加占位变量和语句。

#占位变量
{ {var_name} }

#for循环
{% for item in items %}
....
{% endfor %}

#if语句
{% if condition1 %}
...
{% elif condition2 %}
...
{% else condition3 %}
...
{% endif %}

如:

我们可以在templates文件夹中为lookup添加info.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ topic }}</title>
</head>
<body>
    <table>
        <caption>{{ topic }}</caption>
        <tr>
            {% for head in  heads %}
                <th>{{ head }}</th>
            {% endfor %}
        </tr>
        {% for row in rows %}
            <tr>
                {% for item in row %}
                    <td>{{ item }}</td>
                {% endfor %}
            </tr>
        {% endfor %}
    </table>
</body>
</html>
使用模板文件结合数据模型编写视图

我们可以导入render函数,以其返回值-----一个HttpResponse对象,来作为视图函数的返回值

render函数接受三个参数,第一个是请求对象request,第二个是模板文件的路径(相对templates),第三个是context字典-----即要替换模板文件中的占位变量的key-value组成的字典。

为了准备好context字典,我们可以对模型类进行增删查改操作,以获得对应数据。

数据模型增删查改

以下操作(除导入)在view.py的视图函数中进行

from lookup.models import Books  #导入模型类

"""增加数据"""
#方法1
#创建模型类实例-----映射数据行
newbook=Books(name="倚天屠龙记",price=42,writer=2,out_time="1961/01/01")
#保存到数据库中
newbook.save()

#方法2
#直接通过model.objects的方法
Books.objects.create(name="倚天屠龙记",price=42,writer=2,out_time="1961/01/01")

"""修改数据"""
#方法1
#查询以获得对象(数据行)
book=Books.objects.get(name='倚天屠龙记')
#直接修改查询到的对象的属性
book.out_time="1961/01/02"
#保存到数据库中
book.save()

#方法2
#fliter查询对象,update更新数据
Books.objects.filter(name='倚天屠龙记').update(out_time="1961/01/02")

"""删除数据"""
#方法1
book=Books.objects.get(name='倚天屠龙记')
person.delete()

#方法2
Books.objects.filter(name='倚天屠龙记').delete()

"""查询数据"""
#查询满足某条件的一个数据行
Books.objects.get(condition)
#查询所有数据行
Books.objects.all()
#查询满足某条件的多个数据行
Books.objects.fliter(condition)
#查询不满足条件的多个数据行
Books.objects.exclude(condition)

其中,查询时的condition的格式是

属性__运算符或限制=

Books.objects.filter(id__exact=1)  #id准确地等于1

Books.objects.filter(name__contains='传')  #name里含有“传”
Books.objects.filter(name__endswith='传')  #name以"传"结尾
Books.objects.filter(name__startswith='射')  #name以“射”开头

Books.objects.filter(introdunction__isnull=True)  #名字为NULL

Books.objects.filter(id__in=[1,3,5])  #id在1,3,5范围中

Books.objects.filter(id__gt=3) #greater than,大于
Books.objects.filter(id__gte=3) #greater than and equal,大于等于
Books.objects.filter(id__lt=3) #less than,小于
Books.objects.filter(id__lte=3) #less than and equal,小于等于

Books.objects.filter(birth_year|birth_month|birth_day|birth_week_day|birth_hour|birth_minute|birth_second=...)  #特定日期
编写视图

利用查询到的模型对象,我们可以替换模板html文件中的占位变量,并用render渲染返回。

如:

def books_info(request):
    """书籍挑选页面"""
    books_data = Books.objects.all()
    context = {"topic": "书籍挑选", "heads": ["名称", "作者", "价格", "出版时间"], "rows": []}
    for book in books_data:
        context["rows"].append([book.name,book.writer.name,book.price,book.out_time])
    print(context)
    return render(request,"lookup/info.html",context)

替换占位变量后,最后的显示效果是这样的:

在这里插入图片描述


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木子希卡利

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值