Djiango框架秘籍
Posted 关灯吃面
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Djiango框架秘籍相关的知识,希望对你有一定的参考价值。
Django目录介绍、路由系统、 ORM表的创建
Django目录介绍 django-admin startproject mysite 在终端创建目录 cd mysite python manage.py startapp app01 创建一个app project - app01 -migrations 和数据库相关,和modal相关 - admin Django自带后台管理相关配置 - modal 写类,根据类创建数据库表 - test 单元测试 - views 业务处理,业务可以分类 - app02 - app03 1. 路由系统(位置参数和形式参数不要不要混用,*args,**kwargs可以接收参数) url -> 函数 a. /login/ -> def login SEO权重不高 b. /add-user/(\\d+)/ -> def add_user(request,a1) /add-user/(\\d+)/(\\d+)/ -> def add_user(request,a1,a2) 位置参数 c. /add-user/(?P<a1>\\d+)/ -> def add_user(request,a1) 形式参数 url(r\'^index/\', views.index), 访问时必须index/这种形式 url(r\'^index$\', views.index), 访问时必须index这种形式 url(r\'^index\', views.index), 访问时index开头的任意字符串都可以访问 url(r\'^index/(\\d+).html\', views.index), 访问时必须index/(\\d+).html开头的这种形式 url(r\'^\', views.index) 没有匹配成功,设置默认html PS: 终止符: ^edit$ 伪静态 提高SEO权重 url(r\'^edit/(\\w+).html$\', views.edit), d. 路由分发 urls.py中 导入from django.conf.urls import include url(r\'^app01/\', include(\'app01.urls\')), 先在总路由匹配app路径,然后去该app下urls.py中去匹配路径 app01.urls.py url(r\'^index.html$\', views.index), e. 路由系统之别名反向生成url 根据名称可以反向生成URL 1. url(r\'^index/\', views.index,name="n1) 在Python代码中,在viws.py中 def index(request): from django.urls import reverse v = reverse(\'n1\') print(v) #生成url路径/index/ url(r\'^index/(\\d+)/\', views.index,name="n1) 在Python代码中,在viws.py中 def index(request,a1): from django.urls import reverse v = reverse(\'n1\',args={451}) print(v) #生成url路径/index/451/ url(r\'^index/(?P<a1>\\d+)/\', views.index,name="n1) 在Python代码中,在viws.py中 def index(request,a1): from django.urls import reverse v = reverse(\'n1\',kwargs={\'a1\':1111}) print(v) #生成url路径/index/1111/ 2. 在路由文件中 url(r\'^login/\', views.login,name=\'m1\') 在html文件中 {% url "m1" %} 提交就可以找到/login/路径 在路由文件中 url(r\'^login/(\\W)/\', views.login,name=\'m1\') url(r\'^login/(\\W).html$\', views.login,name=\'m1\') 在html文件中 {% for i in user_list %} <li>{{ i }}|<a href="{% url "m1" i %}">编辑</a></li> {% endfor %} 提交就可以找到/login/i路径 提交就可以找到/login/i.html路径 3. ORM操作 ORM利用pymysql第三方工具连接数据库 默认:使用SQLlite 数据库 Http请求: url -> 视图(模板+数据) 步骤: 1. 创建数据库:在数据库创建70db 2. 在settings中设置 # DATABASES = { # \'default\': { # \'ENGINE\': \'django.db.backends.sqlite3\', # \'NAME\': os.path.join(BASE_DIR, \'db.sqlite3\'), # } # } DATABASES = { \'default\': { \'ENGINE\': \'django.db.backends.mysql\', \'NAME\':\'70db\', \'USER\': \'root\', \'PASSWORD\': \'\', \'HOST\': \'localhost\', \'PORT\': 3306, } } 3. 在项目__init__.py中更换默认连接数据库的方式,MySQLDB(修改django默认连接mySQL方式) import pymysql pymysql.install_as_MySQLdb() 4.在app下的models.py下:创建表 from django.db import models class user_group(models.Model): title = models.CharField(max_length=32) class user_info(models.Model): id = models.BigAutoField(primary_key=True) #这一列不写也会自动生成 username=models.CharField(max_length=32) password=models.CharField(max_length=64) # age = models.IntegerField(null=True) #设置可以为空,创建表后插入这一列时可以这么设置 age = models.IntegerField(default=1) #默认生成ug_id,设置可以为空,创建表后插入这一列时可以这么设置 ug = models.ForeignKey("user_group",null=True) 5.在配置中注册app INSTALLED_APPS = [ \'django.contrib.admin\', \'django.contrib.auth\', \'django.contrib.contenttypes\', \'django.contrib.sessions\', \'django.contrib.messages\', \'django.contrib.staticfiles\', \'app01\' ] 6.创建数据表 命令: python manage.py makemigrations python manage.py migrate
ORM表的操作
ORM操作表: 创建表 修改表 删除表 操作数据行: 增删改查 基于ORM实现组表操作 #新增 models.user_group.objects.create(title="销售部") models.user_info.objects.create(user=\'root\',password=\'pwd\',age=18,ug_id=1) 查找 group_list = models.user_group.objects.all() models.user_group.objects.all().count() 统计个数
group_list = models.user_group.objects.filter(id=1) group_list = models.user_group.objects.filter(id__gt=1) #大于 group_list = models.user_group.objects.filter(id__lt=1) #小于 print(group_list) #group_list是QuerySet类型,可以看成列表 group_list QuerySet类型(列表) QuerySet类型[obj,obj,obj] for row in group_list: print(row.id,row.title) models.user_info.objects.all() 删除 models.user_group.objects.filter(id=2).delete() 更新 models.user_group.objects.filter(id=2).update(title=\'公关部\') 基于ORM实现员工表操作 1.增加 models.UserInfo.objects.create(user=\'root\',password=\'123\',age=10,ug_id=1) obj = models.UserGroup.objects.filter(id=1).first() #直接取一个值
models.UserInfo.objects.create(user=\'root\',password=\'123\',age=10,ug=obj) 2. 删除: models.UserInfo.objects.filter(id=2).delete() 3. 修改: models.UserInfo.objects.filter(id=2).update(title=\'公关部\') 4. 查询: group_list = models.UserInfo.objects.all() group_list获取的是QuerySet,内部元素是UserInfo对象,每一个对象代指一行数据, 对象中如果包含ForeignKey,则代指与其关联表的一行数据 for row in group_list: print(row.user) print(row.age) print(row.ug_id) # 用户信息关联的部门ID print(row.ug.title) # 用户信息关联的部门名称
获取QuerySet(查询集)
# 获取QuerySet(查询集) 1.正向操作、反向操作(连表查询) QuerySet[obj,obj,obj] result = models.UserInfo.objects.all() for obj in result: print(obj.name,obj.age,obj.ut_id,obj.ut.title) 正向操作
UserInfo,ut是FK字段 - PS: 一个用户只有一个用户类型 obj = models.UserInfo.objects.all().first() print(obj.name,obj.age,obj.ut.title) 反向操作
UserType, 表名小写_set.all() - PS: 一个用户类型下可以有很多用户 obj = models.UserType.objects.all().first() print(\'用户类型\',obj.id,obj.title) for row in obj.userinfo_set.all(): print(row.name,row.age) result = models.UserType.objects.all() for item in result: print(item.title,item.userinfo_set.filter(name=\'xx\'))
2.数据获取多个数据时 1.列表查询集 [obj,obj,obj,] models.UserInfo.objects.all() models.UserInfo.objects.filter(id__gt=1) result = models.UserInfo.objects.all() for item in result: print(item.name,item.ut.title) 反向跨表:
1. 小写的表名_set
obj = UserGroup.objects.all().first()
result = obj.userinfo_set.all() [userinfo对象,userinfo对象,]
2.字典查询集 [{id:1,name:fd},{id:1,name:fd},{id:1,name:fd},] models.UserInfo.objects.all().values(\'id\',\'name\') models.UserInfo.objects.filter(id__gt=1).values(\'id\',\'name\') 无法跨表 result = models.UserInfo.objects.all().values(\'id\',\'name\') for item in result: print(item[\'id\'],item[\'name\']) 字典查询集正向跨表 __ result = models.UserInfo.objects.all().values(\'id\',\'name\',"ut__title") for item in result: print(item[\'id\'],item[\'name\'],item[\'ut__title\']) 反向跨表:
2. 小写的表名
v = UserGroup.objects.values(\'id\',\'title\')
v = UserGroup.objects.values(\'id\',\'title\',\'小写的表名称\')
v = UserGroup.objects.values(\'id\',\'title\',\'小写的表名称__age\')
3.元组查询集 [(1,df),(2,\'df\')] models.UserInfo.objects.all().values_list(\'id\',\'name\') models.UserInfo.objects.filter(id__gt=1).values_list(\'id\',\'name\') 无法跨表 result = models.UserInfo.objects.all().values_list(\'id\',\'name\') for item in result: print(item[0],item[1]) 元组查询集正向跨表 __ result = models.UserInfo.objects.all().values_list(\'id\',\'name\',"ut__title") for item in result: print(item[0],item[1],item[2])
反向跨表:
3. 小写的表名
v = UserGroup.objects.values_list(\'id\',\'title\')
v = UserGroup.objects.values_list(\'id\',\'title\',\'小写的表名称\')
v = UserGroup.objects.values_list(\'id\',\'title\',\'小写的表名称__age\')
select_related、prefetch_related连表查询
select_related()主要针一对一和多对一关系进行优化,使用SQL的JOIN语句进行优化
prefetch_related()对于多对多字段和一对多字段进行优化
参考:http://blog.csdn.net/secretx/article/details/43964607
select_related: 查询主动做连表,连表查询速度慢(适用外键对应的表数据量少时使用) q = models.UserInfo.objects.all().select_related(\'ut\',\'gp\') # select * from userinfo # select * from userinfo inner join usertype on ... for row in q: print(row.name,row.ut.title) prefetch_related: 不做连表,做多次查询(使用外键对应的表数据量大,数据频繁查询时使用) q = models.UserInfo.objects.all().prefetch_related(\'ut\') # select * from userinfo; # Django内部:ut_id = [2,4] # select * from usertype where id in [2,4] for row in q: print(row.id,row.ut.title)
related_query_name和related_name的操作:
class Boy(models.Model): name=models.CharField(max_length=32) bpwd = models.IntegerField() class Girl(models.Model): nick = models.CharField(max_length=32) gpwd = models.IntegerField() class Love(models.Model): b=models.ForeignKey(\'Boy\') g=models.ForeignKey(\'Girl\') #可以如上这么写,会自动关联表的自增id,也可以指定表和关联id,如下: #b = models.ForeignKey(to=\'Boy\',to_field=\'id\') #g = models.ForeignKey(to=\'Girl\',to_field=\'id\')
class UserInfo(models.Model): nickname = models.CharField(max_length=32) username = models.CharField(max_length=32) password = models.CharField(max_length=64) gender_choices = ( (1,\'男\'), (2,\'女\'), ) gender = models.IntegerField(choices=gender_choices) class U2U(models.Model): #g = models.ForeignKey(\'UserInfo\',related_query_name=\'boys\') #b = models.ForeignKey(\'UserInfo\',related_query_name=\'girls\') g = models.ForeignKey(\'UserInfo\',related_name=\'boys\') b = models.ForeignKey(\'UserInfo\',related_name=\'girls\') 外键的操作: related_query_name obj对象男.girls_set.all() obj对象女.boys_set.all() related_name obj对象男.girls.all() obj对象女.boys.all() def test(request): #两种创建数据的方式: models.U2U.objects.create(b_id=2,g_id=6) models.U2U.objects.create(b_id=1,g_id=6) boy = models.UserInfo.objects.filter(gender=1,id=2).first() girl = models.UserInfo.objects.filter(gender=2,id=6).first() models.U2U.objects.create(b=boy,g=girl) #创建数据时可以放对象 外键的操作举例: UserInfo对象 xz = models.UserInfo.objects.filter(id=1).first() # 和徐峥有关系的所有信息:U2U列表[U2U对象,2U对象,2U对象,] result = xz.girls.all() for u in result: # U2U对象 print(u.g.nickname)
v.query 查询原生sql语句
一对一操作的正反向:
# obj = models.Blog.objects.filter(site=site).first()
# print(obj.user.nickname)
# obj = models.UserInfo.objects.filter(username=\'sw\').first()
# print(obj.blog.site) onetoone 反向操作时
多对多操作:有外键的情况查询操作
class Boy(models.Model): name = models.CharField(max_length=32) class Girl(models.Model): nick = models.CharField(max_length=32) class Love(models.Model): b = models.ForeignKey(\'Boy\') g = models.ForeignKey(\'Girl\') class Meta: #联合唯一索引 unique_together = [ (\'b\',\'g\'), ] 1. 和方少伟有关系的姑娘 obj = models.Boy.objects.filter(name=\'方少伟\').first() love_list = obj.love_set.all() for row in love_list: print(row.g.nick) love_list = models.Love.objects.filter(b__name=\'方少伟\') for row in love_list: print(row.g.nick) 连表操作: love_list = models.Love.objects.filter(b__name=\'方少伟\').values(\'g__nick\') for item in love_list: print(item[\'g__nick\']) 连表操作: love_list = models.Love.objects.filter(b__name=\'方少伟\').select_related(\'g\') for obj in love_list: print(obj.g.nick)
多对多操作:ManyToManyField、杂交、自定义关系表
1. ManyToManyField class Boy(models.Model): name = models.CharField(max_length=32) m = models.ManyToManyField(\'Girl\') #django内置方式这一行会生成第三张关系表,即app01_boy_m,只能生成三列,如果有多行信息,自己写在第三张表 #m = models.ManyToManyField(\'Girl\',through="Love",through_fields=(\'b\',\'g\',)) #杂交,如果这样写就只生成LOVE表 class Girl(models.Model): nick = models.CharField(max_length=32) #自定义关系表 #class Love(models.Model): # b = models.ForeignKey(\'Boy\') # g = models.ForeignKey(\'Girl\') # class Meta: #联合唯一索引 # unique_together = [ # (\'b\',\'g\'), # ] 增加: obj = models.Boy.objects.filter(name=\'方少伟\').first() print(obj.id,obj.name) obj.m.add(2) obj.m.add(2,4) obj.m.add(*[1,]) 删除: obj.m.remove(1) obj.m.remove(2,3) obj.m.remove(*[4,]) 覆盖修改: obj.m.set([1,]) q = obj.m.all() # [Girl对象] print(q) obj = models.Boy.objects.filter(name=\'方少伟\').first() girl_list = obj.m.all() obj = models.Boy.objects.filter(name=\'方少伟\').first() girl_list = obj.m.all() girl_list = obj.m.filter(nick=\'小鱼\') print(girl_list) 删除第三张表的数据: obj = models.Boy.objects.filter(name=\'方少伟\').first() obj.m.clear() 反向操作: obj = models.Girl.objects.filter(nick=\'小鱼\').first() print(obj.id,obj.nick) v = obj.boy_set.all() print(v) 2.杂交: #m = models.ManyToManyField(\'Girl\',through="Love",through_fields=(\'b\',\'g\',)) obj = models.Boy.objects.filter(name=\'方少伟\').first() # obj.m.add(1) 因为有ManyToManyField,所以不行,因为可能第三张表还有其他列 # obj.m.remove(1) 因为有ManyToManyField,所以不行,因为可能第三张表还有其他列 # obj.m.clear() 可以 v = obj.m.all() 可以 print(v) 3. 自定义关系表
多对多操作,有无第三张表的情况:
# 自己反向关联,需要通多中间的表 # v= models.Article.objects.filter(blog=blog,article2tag__tag=val) # 通过M2M字段,直接关联到另一张表,跳过中间件 # v= models.Article.objects.filter(blog=blog,tags__nid=val)
class Article(models.Model): nid = models.BigAutoField(primary_key=True) title = models.CharField(verbose_name=\'文章标题\',max_length=128) summary = models.CharField(verbose_name=\'文章简介\',max_length=255) read_count = models.IntegerField(default=0) comment_count = models.IntegerField(default=0) up_count = models.IntegerField(default=0) down_count = models.IntegerField(default=0) create_time = models.DateTimeField(verbose_name=\'创建时间\',auto_now_add=True) blog = models.ForeignKey(verbose_name=\'所属博客\',to=\'Blog\',to_field=\'nid\') category = models.ForeignKey(verbose_name=\'文章类型\',to=\'Category\'以上是关于Djiango框架秘籍的主要内容,如果未能解决你的问题,请参考以下文章应用安全 - 编程语言 | 框架 - PHP - Djiango - 漏洞 -汇总