python【第十九篇】Django进阶
1.路由系统优化
1.1 路由分发
前面我们已经知道,在工程名下的urls.py中写我们的路由映射关系,那么问题来了,假设我们有10个app,如果把所有的url映射都写在urls.py文件中,那么每一个app的路由都得到这里写,岂不是很麻烦?而且url多了还不好找,是吧?
所以,我们其实可以这样:
(1)在urls.py中这样写:
from django.conf.urls import url
from django.contrib import admin
from django.conf.urls import include # 导入include
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^user/', include('user.urls')), # 格式就是 url(r'^app01/', include('app01.urls')),
]
'''
----------------------------------------------------------------------------------------------
# 如果有多个app,那么就写成:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^app01/', include('app01.urls')),
url(r'^app02/', include('app02.urls')),
url(r'^app03/', include('app03.urls')),
]
----------------------------------------------------------------------------------------------
'''
(2)在到每个app目录下,新建一个同名的urls.py,在其中写到:
#! /usr/bin/env python3
# -*- coding:utf-8 -*-
from django.conf.urls import url
from user import views # 从当前app导入view
# 下面就可以写对应的映射关系了,不过访问时url就形如:127.0.0.1:8000/user/login/了,不再是127.0.0.1:8000/login/
urlpatterns = [
url(r'^login/', views.login),
url(r'^init/', views.db_init),
url(r'^index/', views.index),
url(r'^useradd/', views.user_add),
url(r'^userdel/', views.user_del),
url(r'^detail-(?P<nid>\d+)/', views.user_detail),
url(r'^edit-(?P<nid>\d+)/', views.user_edit),
url(r'^update/', views.update),
url(r'^group-add/', views.group_add),
url(r'^group-del/', views.group_del),
]
也就是说每个app的路由映射关系,都到了自己目录下面,是不是方便了很多?这就是路由分发。
1.2 通过路由传值
urls.py中这样写:
url(r'^detail-(\d+)-(\d+).html', views.detail),
对应views.py中的函数:
# 假设\d+匹配到的分别是2,9
#法1
def detail(request, nid, uid):
pass
#法2
def detail(request, *args):
args = (2,9)
#法3
def detail(request, *args, **kwargs):
args = (2,9)
kwargs = {}
urls.py中这样写:
url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail)
对应views.py中的函数:
def detail(request, nid, uid):
pass
def detail(request, **kwargs):
kwargs = {'nid': 1, 'uid': 3}
def detail(request, *args, **kwargs):
args = (2,9)
2.Model
python涉及数据库操作时,我们一般都会这样处理:
(1)
创建数据库,设计表结构和字段
使用PyMysql来连接数据库,并且编写数据访问层代码
业务逻辑层去调用数据访问层执行数据库操作
(2)另外就是用关系对象映射(Object Relational Mapping,简称ORM)来处理,前面我们已经学过sqlalchemy这个模块来操作数据库了,而我们强大的django也有自己的一套ORM
其他语言中:
PHP:activerecord
Java:Hibernate
C#:Entity Framework
django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表。
2.1 创建表
(1)基本表结构:
from django.db import models
class UserGroup(models.Model):
"""用户组表"""
group_name = models.CharField(max_length=32) # 用户组名称
更多字段:
1、models.AutoField 自增列 = int(11)
如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
2、models.CharField 字符串字段
必须 max_length 参数
3、models.BooleanField 布尔类型=tinyint(1)
不能为空,Blank=True
4、models.ComaSeparatedIntegerField 用逗号分割的数字=varchar
继承CharField,所以必须 max_lenght 参数
5、models.DateField 日期类型 date
对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
6、models.DateTimeField 日期类型 datetime
同DateField的参数
7、models.Decimal 十进制小数类型 = decimal
必须指定整数位max_digits和小数位decimal_places
8、models.EmailField 字符串类型(正则表达式邮箱) =varchar
对字符串进行正则表达式
9、models.FloatField 浮点类型 = double
10、models.IntegerField 整形
11、models.BigIntegerField 长整形
integer_field_ranges = {
'SmallIntegerField': (-32768, 32767),
'IntegerField': (-2147483648, 2147483647),
'BigIntegerField': (-9223372036854775808, 9223372036854775807),
'PositiveSmallIntegerField': (0, 32767),
'PositiveIntegerField': (0, 2147483647),
}
12、models.IPAddressField 字符串类型(ip4正则表达式)
13、models.GenericIPAddressField 字符串类型(ip4和ip6是可选的)
参数protocol可以是:both、ipv4、ipv6
验证时,会根据设置报错
14、models.NullBooleanField 允许为空的布尔类型
15、models.PositiveIntegerFiel 正Integer
16、models.PositiveSmallIntegerField 正smallInteger
17、models.SlugField 减号、下划线、字母、数字
18、models.SmallIntegerField 数字
数据库中的字段有:tinyint、smallint、int、bigint
19、models.TextField 字符串=longtext
20、models.TimeField 时间 HH:MM[:ss[.uuuuuu]]
21、models.URLField 字符串,地址正则表达式
22、models.BinaryField 二进制
23、models.ImageField 图片
24、models.FilePathField 文件
(2)连表结构:
(1)一对多:models.ForeignKey(其他表)
应用场景:
- 一对多:当一张表中创建一行数据时,有一个单选的下拉框(可以被重复选择)
例如:创建用户信息时候,需要选择一个用户类型【普通用户】【金牌用户】【铂金用户】等。
示例:
from django.db import models
class UserGroup(models.Model):
"""用户组表"""
group_name = models.CharField(max_length=32) # 用户组名称
class UserInfo(models.Model):
"""用户信息表"""
name = models.CharField(max_length=32) # 用户的姓名
username = models.CharField(max_length=32) # 用户名
password = models.CharField(max_length=64) # 用户密码
user_type_choice = (
(0, u'普通用户'),
(1, u'管理员用户'),
)
user_type = models.IntegerField(choices=user_type_choice, default=0) # 用户类型
date = models.DateField(auto_now=True) # 创建日期
remark = models.CharField(max_length=64) # 备注
user_group = models.ForeignKey(UserGroup) # 关联的用户组
2.2 操作表:
(1)创建表结构:
我们在modes中已经写好表的类了,那么我们可以通过命令行:
python manage.py makemigrations
python manage.py migrate
这样表结构就创建好了,如下所示:

(2)增删改查:
# 示例表结构类
class GroupInfo(models.Model):
group_name = models.CharField(max_length=32)
class UserInfo(models.Model):
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
# 创建
# 法1
# models.UserInfo.objects.create(username="zingp", password="123")
# 法2
# user_dic = {"username": "alex", "password": "123"}
# models.UserInfo.objects.create(**user_dic)
# 法3
# obj = models.UserInfo(username="root", password="123")
# obj.save()
# 查
# result = models.UserInfo.objects.all() # 查询所有
# result = models.UserInfo.objects.filter(username="root", password="123") # 根据条件过滤
# for row in result:
# print(row.id, row.username)
# models.UserInfo.objects.get(id=1) # 获取单条数据,不存在则报错(不建议)
# 删除
#models.UserInfo.objects.filter(username="alex").delete()
# 更新
#models.UserInfo.objects.filter(id=3).update(password="8888")
python【第十九篇】Django进阶的更多相关文章
- Python之路(第二十九篇) 面向对象进阶:内置方法补充、异常处理
一.__new__方法 __init__()是初始化方法,__new__()方法是构造方法,创建一个新的对象 实例化对象的时候,调用__init__()初始化之前,先调用了__new__()方法 __ ...
- Python之路【第十九篇】:爬虫
Python之路[第十九篇]:爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用 ...
- 第十九章 Django的ORM映射机制
第十九章 Django的ORM映射机制 第一课 Django获取多个数据以及文件上传 1.获取多选的结果(checkbox,select/option)时: req.POST.getlist('fav ...
- python第二十九课——文件读写(复制文件)
自定义函数:实现文件复制操作有形参(2个) 没有返回值相似版(不用) def copyFile(src,dest): #1.打开两个文件:1个关联读操作,1个关联写操作 fr=open(src,'rb ...
- python第二十九课——文件读写(读取读取中文字符)
演示:读取中文字符 结论: 1).如果不设置encoding,默认使用gbk进行编解码 2).如果编码和解码不一致,最终导致报错,但是一旦设置了errors='ingore',那么就不会报错,而采取乱 ...
- Egret入门学习日记 --- 第十九篇(书中 8.8~8.10 节 内容)
第十九篇(书中 8.8~8.10 节 内容) 开始 8.8节. 重点: 1.类型推断. 2.类型强制转换,使其拥有代码提示功能. 3.除了TS自带的类型判断,Egret官方也提供了类型判断的方法. 操 ...
- Android UI开发第三十九篇——Tab界面实现汇总及比较
Tab布局是iOS的经典布局,Android应用中也有大量应用,前面也写过Android中TAb的实现,<Android UI开发第十八篇——ActivityGroup实现tab功能>.这 ...
- [资料分享]Python视频教程(基础篇、进阶篇、项目篇)
Python是一种开放源代码的脚本编程语言,这种脚本语言特别强调开发速度和代码的清晰程度.它可以用来开发各种程序,从简单的脚本任务到复杂的.面向对象的应用程序都有大显身手的地方.Python还被当作一 ...
- Python之路【第二十九篇】:django ORM模型层
ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的 ...
随机推荐
- GNU LIBC源代码学习之strcmp
比較两个字符串 我的代码块 #include <string.h> int my_strcmp(const char* s1,const char * s2) { if((s1==NULL ...
- 批处理:循环解压不同文件夹下的zip压缩包
结构如下 A文件夹: A1文件.zip A2文件.zip A3文件.zip B文件夹: B1文件.zip B2文件.zip B3文件.zip ...... 批处理文件:rezip.bat如下 @ech ...
- JDK的帧--java.util包装工具库
题词 JDK,Java Development Kit. 首先,我们必须认识到,,JDK但,但设置Java只有基础类库.它是Sun通过基础类库开发,这是唯一的.JDK书写总结的类库.从技术含量来说,还 ...
- python 2016 大会 pyconsk ppt ---python dtrace
https://github.com/pyconsk/2016-slides PyCon SK 2016 - March 2016 1DTrace and PythonJesús Cea Aviónj ...
- MySQL协议分析
MySQL协议分析 标签: mysql 2015-02-27 10:22 1807人阅读 评论(1) 收藏 举报 分类: 数据库(19) 目录(?)[+] 1 交互过程 MySQL客户端与 ...
- NIO学习:异步IO实例
工作模式: 客户端代码: package demos.nio.socketChannel; import java.io.ByteArrayOutputStream; import java.io.I ...
- Android 自定义View修炼-仿360手机卫士波浪球进度的实现
像360卫士的波浪球进度的效果,一般最常用的方法就是 画线的方式,先绘sin线或贝塞尔曲线,然后从左到右绘制竖线,然后再裁剪圆区域. 今天我这用图片bitmap的方式,大概的方法原理是: (1)首先用 ...
- Nexus搭建Maven服务器
参考:http://blog.csdn.net/ichsonx/article/details/14642897 1. 为什么使用Nexus 如果没有私服,我们所需的所有构件都需要通过maven的中央 ...
- Flume简介与使用(一)——Flume安装与配置
Flume简介与使用(一)——Flume安装与配置 Flume简介 Flume是一个分布式的.可靠的.实用的服务——从不同的数据源高效的采集.整合.移动海量数据. 分布式:可以多台机器同时运行采集数据 ...
- log4j中存在日志无法打印问题解决
我在项目中配置双数据中心,原来类包名称前最都是一致的,后来由于项目的需要根据数据来源命名不同的类包名称,这个导致一个问题,sql语句运行无法正常打印出来,提示以下内容: log4j:WARN No a ...