初识Django
Django介绍
Django是一个开放源代码的Web应用框架,由python写成。它源自一个在线新闻Web站点,于2005年以开源的形式被释放出来。它采用了MTV的框架模式,即模型M,模板T和 视图V。
Django框架再近年来发展迅速,应用也越来越广泛
D讲哦是一个基于MVC架构构造的框架,但是在Django中,控制器接收用户输入的部分由框架自行处理。所以Django更关注的是模型(Model)、模板(Template)和视图(Views),称为MTV模式。
MVC 模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。
MVC 以一种插件式的、松耦合的方式连接在一起。
- 模型(M)- 编写程序应有的功能,负责业务对象与数据库的映射(ORM)。
- 视图(V)- 图形界面,负责与用户的交互(页面)。
- 控制器(C)- 负责转发请求,对请求进行处理。
简易图:
用户操作流程图:
MTV 模型
Django 的 MTV 模式本质上和 MVC 是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django 的 MTV 分别是指:
- M 表示模型(Model):编写程序应有的功能,负责业务对象与数据库的映射(ORM)。
- T 表示模板 (Template):负责如何把页面(html)展示给用户。
- V 表示视图(View):负责业务逻辑,并在适当时候调用 Model和 Template。
除了以上三层之外,还需要一个 URL 分发器,它的作用是将一个个 URL 的页面请求分发给不同的 View 处理,View 再调用相应的 Model 和 Template,MTV 的响应模式如下所示:
简易图:
用户操作流程图:
解析:
用户通过浏览器向我们的服务器发起一个请求(request),这个请求会去访问视图函数:
- a.如果不涉及到数据调用,那么这个时候视图函数直接返回一个模板也就是一个网页给用户。
- b.如果涉及到数据调用,那么视图函数调用模型,模型去数据库查找数据,然后逐级返回。
视图函数把返回的数据填充到模板中空格中,最后返回网页给用户。
Django项目的创建
安装Django之后,在cmd中使用命令命令 django-admin startproject ttsx
来创建一个名为ttsx的项目。
目录说明:
- ttsx:** 项目的容器。
- manage.py: 一个实用的命令行工具,可让你以各种方式与该 Django 项目进行交互。
- __init__.py: 一个空文件,告诉 Python 该目录是一个 Python 包。
- /asgi.py: 一个 ASGI 兼容的 Web 服务器的入口,以便运行你的项目。
- /settings.py: 该 Django 项目的设置/配置。
- /urls.py: 该 Django 项目的 URL 声明; 一份由 Django 驱动的网站"目录"。
- /wsgi.py: 一个 WSGI 兼容的 Web 服务器的入口,以便运行你的项目。
创建应用
- 和商品展示有关的应用,叫goods应用。
- 和购物车相关的应用,叫做cart应用
一个应用中包含了该子业务所有的操作。创建这两个应用的命令如下:
python manage.py startapp goods
python manage.py startapp cart
应用是一个Web应用程序,它完成具体的事项 —— 比如一个博客系统、一个存储公共档案的数据库或者一个简单的投票应用。 项目是一个特定网站中相关配置和应用的集合。一个项目可以包含多个应用。一个应用可以运用到多个项目中。
一个应用就创建成功了,目录如下,来解释下每个文件:
polls/
__init__.py # 说明这是个python包
admin.py # 管理后台的文件,本次项目中没有用到
migrations/ # 迁移文件夹,存放一些迁移文件。数据库每次改动都会在这个目录下生成一条记录
__init__.py # 说明这是个python包
models.py # models文件,主要编写一些数据库的表结构,字段等。数据库相关操作写入该文件中【模型文件】
tests.py # 测试用的文件
views.py # 试图函数的文件,大多数我们是在这个文件进行页面逻辑的编写【视图文件】,用来处理逻辑部分
数据库配置
Django ORM
Django 模型使用自带的 ORM。
对象关系映射(Object Relational Mapping,简称 ORM )用于实现面向对象编程语言里不同类型系统的数据之间的转换。
ORM 在业务逻辑层和数据库层之间充当了桥梁的作用。
ORM 是通过使用描述对象和数据库之间的映射的元数据,将程序中的对象自动持久化到数据库中。
使用 ORM 的好处:
- 提高开发效率。
- 不同数据库可以平滑切换。
使用 ORM 的缺点:
- ORM 代码转换为 SQL 语句时,需要花费一定的时间,执行效率会有所降低。
- 长期写 ORM 代码,会降低编写 SQL 语句的能力。
ORM 解析过程:
- 1、ORM 会将 Python 代码转成为 SQL 语句。
- 2、SQL 语句通过 pymysql 传送到数据库服务端。
- 3、在数据库中执行 SQL 语句并将结果返回。
ORM 对应关系表:
配置数据库
将ttsx目录中的seting文件中的DATABASE中的信息修改为:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'ttsx',#数据库名,需要进入mysql命令行创建
'HOST': 'localhost',#数据库的地址
'PORT': '3306',#mysql端口,默认为3306
'USER': 'root',#mysql数据库登录用户名
'PASSWORD': '123456',#mysql数据库登录密码
}
之后在项目文件目录中的__init__文件中修改为如下:
import pymysql
pymysql.install_as_MySQLdb()
数据表和字段介绍
一共需要四张数据库表:
GoodsCategory表,用于存储商品分类信息,它的列包括:
- 分类显示名称
- 分类显示样式
- 分类显示图片
GoodsInfo表,用于存储商品具体信息,它的列包括:
- 商品名称
- 商品价格
- 商品描述
- 商品分类
商品属于哪个分类,又一个外键关联到主键id
关于购物车的部分,也分为两个表:
OrderInfo表,存储订单基本信息,它的列包括:
- 订单编号
- 收货地址
- 收货人
- 联系电话
- 订单运费
- 订单备注
- 订单状态
OrderGoods表,存储订单所对应的商品信息,它的列包括:
- 订单商品
- 商品数量
- 所属订单
接下来针对分析得到的表结构,创建对应的模型。要注意的是,自定义模型类需要定义在models.py模块中,并且该类必须继承自models.Model类。
在所创建的应用中,models.py就是用来创建数据表的
需要在models.py中写入模型类
必须继承自models.Model类(models模块下的Model类)
对应数据库中的一张表,表里面的字段就是类中的属性
charfield 表示当前字段是一个字符串
ImageField表示当前字段是一个图片。定义完imagefiled之后,实际在数据库中存储的是图片在服务器中的路径
加上一个upload_to属性,表示当前分类的图片要存储到该属性对应的值的文件夹中
普通字段
AutoField:
自增字段,可以随着实例的创建而自动增加.
BooleanField:
布尔类型字段,HTML挂件为CheckBoxInput.取值为:Ture/False
,不能为null
.默认值为None
.
NullBooleanField:
布尔类型,HTML挂件为NullBooleanSelect,取值为:True/False/null
.
CharField:
字符串类型的字段,HTML挂件为TextInput,必须接收一个CharField.max_length
参数来指定其在数据库中的长度.
DateField:
日期字段,使用的是python的datetime.date实例,有几个额外的参数.
DateField.auto_now_add:
取值为False/True
,作用为自动取值为实例创建的时间,创建于.DateField.auto_now:
取值为:False/True
,作用为自动设置值为最后一次保存的时间,更新于.auto_now
,auto_now_add
,default
三个选项是互斥的.
DateTimeFild:
日期类型,使用的是python 的datetime.datetime实例,参数个DateField
一样.
TimeField
:日期类型,使用的是python 的datetime.time实例,参数和上述一样.
查询python参考可知,Data主要用于日期,表示年月日,Time主要用于时间,表示时分秒,而DateTime则是完整的年月日时分秒都有.
DecimalField:
十进制的浮点数字段,使用的是python的Decimal实例表示十进制的浮点数,也就是小数,Html默认挂件为TextInput,接收两个必须参数:
DecimalField.max_digits:
数字的总位数,包括整数和小数部分.DecimalField.decimal_places:
小数的位数
FloatField:
十进制浮点数类型,使用的是python的float数据类型表示小数.
EmailField:
邮件类型,主要用于验证邮件地址的正确性,使用EmailValidator验证.
FileField:
文件字段,用于上传文件.添加该字段后,会获得一个FieldFile
来管理文件.
FilePathField:
文件名类型,实质是一个CharField
类型,只是类容做了限定,只能是文件的路径和名字.
ImageField:
图片类型,除了继承自FileField
外,还提供了额外的功能,比如图片校验等.需要调用Pillow库.
GenericlIPAdressField:
IP地址类型.
SlugField:
段标题,主要用于生成url或者其他唯一的链接.
TextField:
大文本类型,HTML挂件为Textarea.
URLField:
URL类型的字段,根本是CharField.
关系字段
ForeignKey:
外键字段,也叫多对一关系,本Model是多,然后关联一个’一’,比如一个人可以写很多文章,那么此时的文正就是多,而人就是一,然后人就是文章的外键.
ForeignKey.limit_choices_to:
值为一个字典,筛选出满足一定关系的Model实例,使得本Model的选择只能是满足上述模块的Model实例.
ForeginKry.relate_name:
取值为字符串,用于设置本Model在关联实例中的名称.例如:本Model为文章,关联了人作为外键,那么对于人来说,人对他所写的这些文章的称呼就叫做’著作们’,relate_name就表示这个..
则:goods应用中,models.py中的代码如下:
from django.db import models
# Create your models here.
class GoodsCategory(models.Model):
#分类的名称,max_length 最大长度,字段类型
cag_name = models.CharField(max_length=30)
#分类的样式
cag_css = models.CharField(max_length=20)
#分类的图片
cag_img = models.ImageField(upload_to='cag')
#商品表
#模型类
class GoodsInfo(models.Model):
#商品名字
goods_name = models.CharField(max_length=100)
#商品的价格
goods_price = models.IntegerField(default=0)
#商品的描述
goods_desc = models.CharField(max_length=2000)
#商品图片
goods_img = models.ImageField(upload_to='goods')
#商品所属的分类,定义了一个外键
goods_cag = models.ForeignKey('GoodsCategory',on_delete=models.CASCADE)#上面那个GoodsCategory表所对应的外键
cart模块中models.py中的代码如下:
from django.db import models
# Create your models here.
class OrderInfo(models.Model):
"""订单信息模型"""
# 定义一个元组,里面存储订单信息
status = (
(1,'待付款'),
(2,'代发货'),
(3,'待收货'),
(4,'已完成'),
)
#订单编号
order_id = models.CharField(max_length=100)
#收获地址
order_addr = models.CharField(max_length=100)
#收货人
order_recv = models.CharField(max_length=50)
#联系电话
order_tele = models.CharField(max_length=11)
#运费
order_fee = models.IntegerField(default=0)
#订单备注
order_extra = models.CharField(max_length=200)
#订单状态
order_statu = models.IntegerField(default=1,choices=status)
class OrderGoods(models.Model):
"""订单商品模型"""
#所属商品
goods_info = models.ForeignKey('goods.GoodsInfo',on_delete=models.CASCADE)
#商品数量
goods_num = models.IntegerField()
#商品所属订单
goods_order = models.ForeignKey('OrderInfo',on_delete=models.CASCADE)
如果不写主键,django会默认生成一个id的主键
字段常用选项:
选项类型 | 描述 |
---|---|
null | 如果为True,表示允许为空,默认值是False |
db_column | 字段的名称,如果未指定,则使用属性的名称 |
db_index | 若值为True,则会在表中为此字段创建索引,默认值是False |
default | 默认值 |
primary_key | 若值为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用 |
unique | 如果为True,这个字段在表中必须有唯一值,默认值是False |
创建和执行迁移文件生成表
文件中的代码改变之后,数据库中还没有生成那些表,需要执行一些命令来生成表,这就叫创建和执行迁移文件生成表:
在项目目录下,使用命令:
python manage.py makemigrations
来创建迁移文件
如果引用外键的地方没有使用到on_delete=models.CASCADE
则会出现报错:
TypeError: __init__() missing 1 required positional argument: 'on_delete'
报错原因:
classForeignKey(to,on_delete,** options)
多对一的关系,需要两个位置参数:模型相关的类和on_delete选项。(on_delete
实际上并不需要,但是不提供它会给出弃用警告,这在Django 2.0中将是必需的,**1.8及以前的版本不需要)
要创建递归关系,即:与自身具有多对一关系的对象使用。
models.ForeignKey('self', on_delete=models.CASCADE)
创建迁移文件生成表之后,结构如下:
迁移文件的类记录了每个模块中需要生成的数据表名和字段,来生成create语句。这些语句就是根据当前这些文件的内容来生成的
查看该文件所生成的SQL语句:
python manage.py sqlmigrate goods 0001.py
C:\Users\AdminLuo\Desktop\ttsx>python manage.py sqlmigrate goods 0001
--
-- Create model GoodsCategory
--
CREATE TABLE `goods_goodscategory` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `cag_name` varchar(30) NOT NULL, `cag_css` varchar(20) NOT NULL, `cag_img` va
rchar(100) NOT NULL);
--
-- Create model GoodsInfo
--
CREATE TABLE `goods_goodsinfo` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `goods_name` varchar(100) NOT NULL, `goods_price` integer NOT NULL, `goods_desc`
varchar(2000) NOT NULL, `goods_img` varchar(100) NOT NULL, `goods_cag_id` integer NOT NULL);
ALTER TABLE `goods_goodsinfo` ADD CONSTRAINT `goods_goodsinfo_goods_cag_id_a7b17a2d_fk_goods_goodscategory_id` FOREIGN KEY (`goods_cag_id`) REFERENCES `goods_goods
category` (`id`);
CREATE INDEX `goods_goodsinfo_goods_cag_id_a7b17a2d` ON `goods_goodsinfo` (`goods_cag_id`);
注:当前只是生成了语句,还没有执行。
使用命令python manage.py migrate
来执行:
C:\Users\AdminLuo\Desktop\ttsx>python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, cart, contenttypes, goods, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying goods.0001_initial... OK
Applying cart.0001_initial... OK
Applying sessions.0001_initial... OK
数据库操作
插入操作
数据库操作需要使用 python manage.py shell
进入命令行进行操作
进入之后,需要导入goods下的models.py文件from goods.models import *
导入之后,就可以执行插入操作:
categories = [('时令水果','fruit',1),('海鲜水产','seafood',2)
('全品肉类','meet',3),('美味蛋品','egg',4)
('新鲜蔬菜','vegetaables',5),('低温奶制品','ice',6)]
for cag in categories:
c = GoodsCategory()#实例化该模型类
c.cag_name = cag[0]
c.cag_css = cag[1]
c.cag_img = 'images/banner0%d.jpg'%cag[2] #使用占位符
c.save() #执行insert操作
注:暂时还没有该项目所需要使用的图片,无法解析图片地址
接下里再以同样的方式向数据库中插入一条商品数据
from goods.models import *
goods = GoodsInfo()#创建实例化对象
goods.goods_name = '新疆库尔勒香梨5斤'
goods.goods_price = 79
goods.goods_img = 'xiangli'
goods.goods_desc = '库尔勒香梨果面光滑,香气浓郁,酥脆可口'
goods.goods_cag_id = 1 #django会自动生成goods_cag_id属性,用来关联外键id
goods.save()
查询操作
查询操作是项目中使用最多的数据库操作,本项目主要用到了Django框架提供的以下3个方法:
- get方法:查询一条数据,如果返回结果有多条就会报错,如果没有也会报错
- 如果匹配到的对象有多个,则get方法会触发MultipleObjectsReturned异常
- 如果查询不到结果,则将触发DoesNotExist异常
- all方法:获得所有数据
all方法还可以进行切片
所查询出来的是对象,输出使用以下语法:
- filter方法:根据条件过滤数据
虽然使用all方法能够获得一张数据库表中的所有数据的集合,但是在通常情况下,我们往往只需要获取满足特定条件的部分数据。这时,就可以使用filter方法来查询
查询之前,需要导入模型类
GoodsInfo.objects.get(goods_name = '库尔勒香梨') #GoodsInfo模型类下有一个django提供的属性,为objects(称之为管理器,其中封装了模型类的增删改查的方法),其有一个get方法
该语句执行完之后,会返回一个当前goodsinfo的实例化对象
更新操作
Django创建和更新对象使用了同一个方法sava() 。当调用save()方法保存数据的时候,Django会判断当前对象是否有主键,如果逐渐存在则执行更新操作,如果主键不存在则执行插入操作。例如以下代码,将数据库中的商品“库尔勒香梨”的价格进行了修改:
goods = GoodsInfo.objects.get(goods_name='新疆库尔勒香梨5斤')
goods.goods_price = 100
goods.save()
删除操作
删除操作使用了管理器对象的delete方法。例如,以下代码将名为‘新疆库尔勒香梨5斤’的商品进行删除
goods = GoodsInfo.objects.get(goods_name='新疆库尔勒香梨5斤')
goods.delete()
#删除之后如果再执行查询语句,会报错
数据库操作一般都是使用当前你要操作的当前的模型类的objects管理器的方法来完成的
创建视图
视图就是一个函数
goods应用模块下的views.py文件
必须传递一个参数 request 请求对象 里面有用户发送的请求信息,比如url地址和其他数据 注:request可以随便命名
修改之后,goods/views.py文件内容如下:
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
def index(request):
return HttpResponse('hello django')
ttsx/urls.py的文件内容如下:
"""ttsx URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from goods.views import index
urlpatterns = [
path('admin/', admin.site.urls),
#参数一:要访问的url地址的正则匹配
#参数二:要访问的视图的函数名字
path('index/',index ),
]
之后runserver,看到以下页面说明运行成功:
模板文件的配置和使用
再项目根目录下新建一个文件夹,命名为templates(可以随意命名)
新建一个index.html文件
BASE_DIR为项目的跟路径的绝对路径地址
再项目目录中的setting.py文件中修改TEMPLATES中的'DIRS': [],
为'DIRS': [os.path.join(BASE_DIR,'templates')],
注:需要先导入os模块【import os】
之后修改视图文件views.py中的index函数为:
def index(request):
#render函数中,参数一是请求的request对象
# 参数二是需要返回的html页面
return render(request,'index.html')
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!