Django复习
Posted Mitsuis
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django复习相关的知识,希望对你有一定的参考价值。
安装成功后在python配置好环境变量的情况下创建django目录:
-
命令:
# 创建Django程序
django-admin startproject mysite
# 进入程序目录
cd mysite
# 启动socket服务端,等待用户发送请求
python manage.py runserver 127.0.0.1:8080
app01:代码处理目录,可以在终端输入 python manage.py startapp app02 继续创建
CSRF:Django项目同名目录,自取名。其中有DJango配置文件settings,与urls路由映射文件
static:静态文件存放目录,用于存放CSS代码、Bootstrap等文件。
templates:网页模版存放目录,一般存放html文件。
utils:可以存放自定制的模块工具。
db.sqlite3: 数据库文件
1 INSTALLED_APPS = [ 2 \'django.contrib.admin\', 3 \'django.contrib.auth\', 4 \'django.contrib.contenttypes\', 5 \'django.contrib.sessions\', 6 \'django.contrib.messages\', 7 \'django.contrib.staticfiles\', 8 \'app01\', 9 ]
如使用的是mysql,需要注释默认配置,重新进行相关配置
首先修改setting文件:
1 DATABASES = { 2 \'default\': { 3 \'ENGINE\': \'django.db.backends.mysql\', 4 \'NAME\':\'dbname\', 5 \'USER\': \'root\', 6 \'PASSWORD\': \'xxx\', 7 \'HOST\': \'\', 8 \'PORT\': \'3306\', 9 } 10 }
随后在同层目录下的__init__.py文件导入对应模块:
import pymysql
pymysql.install_as_MySQLdb()
最后便可以在app目录下的models通过代码建表。
配置static目录。
1 STATIC_URL = \'/static/\' 2 STATICFILES_DIRS = ( 3 os.path.join(BASE_DIR,\'static\'), 4 )
session配置:
1 SESSION_ENGINE = \'django.contrib.sessions.backends.db\' # 引擎(默认) 2 3 SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认) 4 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认) 5 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认) 6 SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认) 7 SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认) 8 SESSION_COOKIE_AGE = 2592000 # Session的cookie失效日期(2周)(默认) 9 SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认) 10 SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认)
二.路由系统:
存放于urls.py文件。
网址后面的输入URL,对应着Django里的一个函数。
(1)一个URL对应一函数: url(r\'^test.html$\', views.test),
(2)基于正则表达式: /add-user/(\\d+)/ -> def add_user(request,a1) name=n1
url(r
\'^manage/(?P<name>\\w*)/(?P<id>\\d*)\'
, views.manage),
url(r
\'^home\'
, views.home, name
=
\'h1\'
),
url(r
\'^index/(\\d*)\'
, views.index, name
=
\'h2\'
),
根据名称可以反向生成URL
1. 在Python代码中
from django.urls import reverse
v = reverse(\'h1\',kwargs={\'a1\':1111})
print(v)
2.
url(r\'^login/\', views.login,name=\'m1\')
{% url "m1" %}
(4)路由分发:
urls.py
url(r\'^app01/\', include(\'app01.urls\')),
app01.urls.py
url(r\'^index.html$\', views.index),
补充:伪静态。伪静态可以优化网页SEO,在搜索引擎中位置可能更靠前
url(r\'^edit/(\\w+).html$\', views.edit), 以html作为结尾。
三.模版
1.当urls的路由系统设置好后,我们便可以在app01的views.py中编写对应函数。
1 from django.shortcuts import render,HttpResponse,redirect
首先导入需要的模块。HttpResponse返回字符串,render返回网页模版,实际经过编译跟HttpResponse本质一样,redirect用于跳转url.
2.模版语言
Views代码:
1 def login(request): 2 return render(request, \'boys.html\', {\'user_list\': user_list}
html代码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 {#直接显示#} 9 {{ user_list }} 10 11 {#//模版中的for循环#} 12 {% for item in user_list %} 13 <a>{{ item }}</a> 14 {% endfor %} 15 16 {#模版中if判断#} 17 {% if user_list == 1 %} 18 {% else %} 19 {% endif %} 20 21 </body> 22 </html>
母板:当一个网站有很多子链接,大多情况下网站下的所有url都有一个统一的基调,比如导航,侧边栏,配色等,这时为防止每个Url都要重写代码,可以将这些公共的模块提取出来制成模版,以后需要用到直接继承即可,节省代码.
- 母板:{% block title %}{% endblock %}
子板:{% extends "base.html" %} #base.html为母板文件名称。
{% block title %}{% endblock %}
一般母板中可以建3个block,一个存放CSS即style代码,一个存放html 即body中的代码,一个编写JS即script代码.
小组件:当页面有一个小块组件需要反复使用,可以用include。
1 - include 2 - 导入小组件 3 pub.html 4 <div> 5 <h3>特别漂亮的组件</h3> 6 <div class="title">标题:{{ name }}</div> 7 <div class="content">内容:{{ name }}</div> 8 </div> 9 10 11 12 test.html 13 <!DOCTYPE html> 14 <html lang="en"> 15 <head> 16 <meta charset="UTF-8"> 17 <title></title> 18 </head> 19 <body> 20 {% include \'pub.html\' %} 21 {% include \'pub.html\' %} 22 {% include \'pub.html\' %} 23 </body> 24 </html>
帮助方法:从后端传来的值后加 |方法名 即可调用由Django封装的python方法。
{{ item.event_start|date:"Y-m-d H:i:s"}}
{{ bio|truncatewords:"30" }}
{{ my_list|first|upper }}
{{ name|lower }}
simple_tag:(自定义python方法模版可以使用)
a、在app中创建templatetags模块
b、创建任意 .py 文件,如:xx.py
1 #!/usr/bin/env python 2 #coding:utf-8 3 from django import template 4 from django.utils.safestring import mark_safe 5 6 register = template.Library() 7 8 @register.simple_tag 9 def my_simple_time(v1,v2,v3): 10 return v1 + v2 + v3 11 12 @register.simple_tag 13 def my_input(id,arg): 14 result = "<input type=\'text\' id=\'%s\' class=\'%s\' />" %(id,arg,) 15 return mark_safe(result)
c、在使用自定义simple_tag的html文件中导入之前创建的 xx.py 文件名 1 {% load xx %}
d、使用simple_tag
1 {% my_simple_time 1 2 3%} 2 {% my_input \'id_username\' \'hide\'%}
e丶在settings中配置当前app,不然django无法找到自定义的simple_tag,已配置忽略。
1 INSTALLED_APPS = ( 2 \'django.contrib.admin\', 3 \'django.contrib.auth\', 4 \'django.contrib.contenttypes\', 5 \'django.contrib.sessions\', 6 \'django.contrib.messages\', 7 \'django.contrib.staticfiles\', 8 \'app01\', 9 )
- simple_filter
- 最多两个参数,方式: {{第一个参数|函数名称:"第二个参数"}}
- 可以做条件判断
3.模版简单渲染
可以利用Bootstrap与以及font-awesome等插件对HTML模版进行一个简单的页面渲染,使页面看上去更加美观。详细教程与使用方法可以到官网查看。
四.models(Django ORM)
1.基本建表:
1 from django.db import models #导入django ORM对应模块 2 3 # Create your models here. 4 class Class1(models.Model): #继承models模块定制类,即创建表,类名为表明 5 cid = models.AutoField(primary_key=True) #创建主键,AutoField为自增(主键可以不写,不写时默认生成一行名称为ID的主键列) 6 cname = models.CharField(max_length=32) #创建char类型字符串,最大长度32 7 8 class Teacher(models.Model): 9 tid = models.AutoField(primary_key=True) 10 tname = models.CharField(max_length=32) 11 12 class Student(models.Model): 13 sid = models.AutoField(primary_key=True) 14 sname = models.CharField(max_length=32) 15 Class = models.ForeignKey(Class1) #创建外键,括号里面填写外键关系的表名 这个类在生成时,Class列会显示为Class_id即自写的列名加_id 16 17 class Guanxi(models.Model): 18 teacher = models.ForeignKey(Teacher) 19 Class = models.ForeignKey(Class1)
当类表定制完毕时,cmd切换到Django项目的根目录,运行命令:(注意将python添加至环境变量)
python manage.py makemigrations
python manage.py migrate
此时数据表即完成创建成功,如有报错,注意查看某个字段是否类型错误,检查之前步骤是否有遗漏。
如果是用的sqlite创建,可以用pycharm自带的可视化以及Django的sqlite结合查看表。(将项目中的sqlite3拖拽到pycharm编辑器右上角点开的Database中)
2.基于ORM对表进行增删改查:
本次操作在views模块中,因此首先导入之前创建的表类
from app01 import models
1 查: 2 res = models.UserType.objects.all() #获取表所有数据,得到一个QuerySet[obj,obj,obj],类似一个个对象组成的列表,循环列表取到的为对象,拥有表的字段属性。 3 for row in res: 4 print(row.cid,row.cname) 5 6 res = models.UserType.objects.all() .first() #获取表所有数据的第一行,实际为一个Obj对象,可以res.cid,res.cname取值 7 8 res = models.UserType.objects.filter(cid=1) 9 res = models.UserInfo.objects.filter(id__gt=1) id大于1 10 res = models.UserInfo.objects.filter(id__lt=1) id小于1 11 #filter查询时,括号里面可以添加条件,得到的依然为QuerySet,需要取值依旧需要for 循环 或者后面加.first()方法,当然也可以按索引取值,得到的也是obj对象 12 13 res = models.UserInfo.objects.all().values(\'id\',\'name\') #实际还是QuerySet,括号里面可以限定需要查询的列,不同的是,这里循环出来的不再是对象,而是一个个的字典 QuerySet[{\'id\':\'xx\',\'name\':\'xx\'} ] 取值需按字典key取值。 14 # 跨表 __ 15 # result = models.UserInfo.objects.all().values(\'id\',\'name\',"ut__title") 16 # for item in result: 17 # print(item[\'id\'],item[\'name\'],item[\'ut__title\']) 18 19 20 res = models.UserInfo.objects.all().values_list(\'id\',\'name\') #得到QuerySet[(1,\'f\'), ] 循环出来的还是一个个的列表,列表索引取值。 21 22 # 跨表 __ 23 # result = models.UserInfo.objects.all().values_list(\'id\',\'name\',"ut__title") 24 # for item in result: 25 # print(item[0],item[1],item[2]) 26 27 28 29 增: 30 #增加为create(),括号里面填写数据行需要的各个数据即可 31 models.UserType.objects.create(title=\'普通用户\') 32 33 34 35 删: 36 #删除需在查询到数据的基础上,后面加上.delete()方法即可 37 models.UserInfo.objects.filter(id=1).delete() 38 39 40 改: 41 #对应的,修改也是在查询的基础上,加.update()方法 42 models.Student.objects.filter(sid=a1).update(sname=name,Class_id=cid) 43 44 #外键操作:以下操作基于2个表已经建立外键关系的基础 45 ##正向操作: 46 # UserInfo,ut是FK字段 - 正向操作 PS: 一个用户只有一个用户类型 47 obj = models.UserInfo.objects.all().first() 48 print(obj.name,obj.age,obj.ut.title) 49 #通过.外键名.对应关系表的字段列名即可拿到UserType表里面的title列值 50 #同样的如果有多个关系表连表操作时,可以一直.外键无穷无尽的连表取到需要的值 51 52 #反向操作: 53 # UserType, 表名小写_set.all() - 反向操作 PS: 一个用户类型下可以有很多用户 54 obj = models.UserType.objects.all().first() #取到用户类型的其中一个Obj 55 print(\'用户类型\',obj.id,obj.title) 56 #通过用户类型查看该类型下有多少个用户 57 for row in obj.userinfo_set.all(): 58 print(row.name,row.age) 59 60 61 result = models.UserType.objects.all() 62 for item in result: 63 print(item.title,item.userinfo_set.filter(name=\'xx\'))
1 有三个表: 2 class Boy(models.Model): 3 name = models.CharField(max_length=32) 4 5 class Girl(models.Model): 6 nick = models.CharField(max_length=32) 7 8 class Love(models.Model): 9 b = models.ForeignKey(\'Boy\',null=True) 10 g = models.ForeignKey(\'Girl\',null=True) 11 #联合唯一索引 12 #class Meta: 13 # unique_together = [ 14 # (\'b\',\'g\'), 15 #] 16 17 1.通过Boy表中name为条件查找Girl表有关联的nick值: 18 插数据: 19 # obj_list = [ 20 # models.Boy(name=\'刘德华\'), 21 # models.Boy(name=\'张学友\'), 22 # models.Boy(name=\'郭富城\'), 23 # models.Boy(name=\'黎明\'), 24 # ] 25 # objs = [ 26 # models.Girl(nick=\'陈慧琳\'), 27 # models.Girl(nick=\'容祖儿\'), 28 # models.Girl(nick=\'郑秀文\'), 29 # models.Girl(nick=\'蒙嘉慧\'), 30 # ] 31 # models.Boy.objects.bulk_create(obj_list,5) 32 # models.Girl.objects.bulk_create(objs,5) 33 建立关系 34 # models.Love.objects.create(b_id=1,g_id=1) 35 # models.Love.objects.create(b_id=1,g_id=4) 36 # models.Love.objects.create(b_id=2,g_id=2) 37 # models.Love.objects.create(b_id=2,g_id=3) 38 # models.Love.objects.create(b_id=2,g_id=4) 39 多对多的关系查询: 40 # lo_list = models.Love.objects.filter(b__name=\'刘德华\').values(\'b__name\',\'g__nick\') 41 # for i in lo_list: 42 # print(i[\'b__name\'],i[\'g__nick\']) 43 # 44 # lov_list = models.Love.objects.filter(b__name=\'张学友\').select_related(\'b\',\'g\') 45 # for row in lov_list: 46 # print(row.b.name,row.g.nick) 47 48 二。两个表的关系也可以不再建关系表Love,通过Django内置ORM的功能同样可以建立表之间的关系,查找时通过间接查找。 49 class Boy(models.Model): 50 name = models.CharField(max_length=32) 51 m = models.ManyToManyField(\'Girl\') 52 53 class Girl(models.Model): 54 nick = models.CharField(max_length=32) 55 56 如此,同样可以建立关系,只不过增删改查相应也有变化。 57 58 obj = models.Boy.objects.filter(name=\'刘德华\').first() #取到筛选出的Boy对象: 59 #增 60 obj.m.add(1) 61 obj.m.add(*[2,3,]) 62 63 # 删: 64 obj.m.remove(1,) 65 obj.m.remove(*[2,]) 66 67 #改 68 obj.m.set([1,2,]) #实为重置,将之前的全部删除重新建立关系 69 70 #查 71 q = obj.m.all() #q得到对应关系的Girl对象
1 class UserInfo(models.Model): 2 nid = models.AutoField(primary_key=True) 3 username = models.CharField(max_length=32) 4 class Meta: 5 # 数据库中生成的表名称 默认 app名称 + 下划线 + 类名 6 db_table = "table_name" 7 8 # 联合索引 9 index_together = [ 10 ("pub_date", "deadline"), 11 ] 12 13 # 联合唯一索引 14 unique_together = (("driver", "restaurant"),) 15 16 # admin中显示的表名称 17 verbose_name 18 19 # verbose_name加s 20 verbose_name_plural
1 #表结构 2 class UserInfo(models.Model): 3 nickname = models.CharField(max_length=32) 4 username = models.CharField(max_length=32) 5 pwd = models.CharField(max_length=32) 6 sex_choices = ( 7 (1,\'男\'), 8 (2,\'女\'), 9 ) 10 sex = models.IntegerField(choices=sex_choices) #枚举 11 12 class U2U(models.Model): 13 g = models.ForeignKey(\'UserInfo\',related_name=\'boys\') 14 b = models.ForeignKey(\'UserInfo\',related_name=\'girls\') 15 16 # FK自关联一个表时,表就无法自己做约束,只能由自己保证在插入数据时确保插入正确。 17 18 #代码查询: 19 from django.shortcuts import render,HttpResponse 20 from app01 import models 21 22 # Create your views here. 23 def test(request): 24 obj = models.UserInfo.objects.filter(id=1,sex=1).first() #首先查询到一个男生对象 25 l = obj.girls.all() #通过男生对象,再根据设置的别名反向查找到对应的所有女生,此时l是一个U2U的queryset集合。 26 for i in l: #循环每个u2u queryset对象,打印由U2U obj对象通过外键g 正向查找,找到与此男生有关的女生对象。 27 print(obj.nickname,\'--------\',i.g.nickname) 28 29 return HttpResponse(\'ok!\') 30
进阶操作:
1 # 获取个数 2 # 3 # models.Tb1.objects.filter(name=\'seven\').count() 4 5 # 大于,小于 6 # 7 # models.Tb1.objects.filter(id__gt=1) # 获取id大于1的值 8 # model以上是关于Django复习的主要内容,如果未能解决你的问题,请参考以下文章
django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段
django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段