Django的安装方式
- 通过pip install Django===版本号
- 下载源码,进入django的执行目录执行python setup.py install
Django创建工程
- django-admin startproject
- manage.py:项目管理器,与项目进行交互的命令行工具集的入口
- http请求包含两个对象(HttpRequest、HttpResponse):from django.http import HttpResponse,Render
httpresponse 返回的是一个字符串
from django.template import loader,Context
def index(request):
t=loader.get_template("index.html")
c=Context({"user":"ceshi"})
html=t.render(c)
# 这里就是直接读取一个文件,也可以通过读文件的方式实现
return HttpResponse(html)
Django Admin
Admin 是Django自带的一个功能强大的自动化数据管理界面,被授权的用户可以直接在Admin中管理数据库
创建用户
- python manage.py createsuperuser 创建超级用
户
管理数据库
- 在应用下admin.py 文件中引入自身的models 模块 编辑 admin.py:
admin.site.register(models.Article)
Admin增强功能
class ArticleAdmin(admin.ModelAdmin):
list_display=[‘title’:'ceshi']
admin.site.register(Article,ArticleAdmin)
django-crontab
-
将正确和错误日志都输出到 /tmp/load.log
分、时、天、月、年、星期
*/5 * * * * /root/XXXX.sh &>>/tmp/load.log 2>&1 -
名词解释:
在shell中,每个进程都和三个系统文件相关联:标准输入stdin,标准 输出stdout和标准错误stderr,三个系统文件的文件描述符分别为0,1和2。所以这里2>&1的意思就是将标准错误也输出到标准输出当中。
但是,程序输出的 -
crontab 的日志,后台程序运行错误的详情需要配置日志,详情见celery日志,或者有时程序报错:No handlers could be found for logger “django_crontab.crontab”
-
-crontab 会用户的身份执行配置的命令,但是不会加载用户的环境变量,crontab会设置几个默认的环境变量,例如SHELL、PATH和HOME等,一定要注意PATH可不是用户自定义的PATH
我们往往会在.bash_profile文件中定义一些全局的环境变量,但是crontab执行时并不会加载这个文件,所以你在shell中正常执行的程序,放到crontab里就不行了,很可能就是因为找不到环境变量了。要解决这个问题只能是自己加载环境变量了,可以在shell脚本中添加source
$HOME/.bash_profile,或者直接添加到crontab中。0 12 * * * source $HOME/.bash_profile && $HOME/path/to/script > $HOME/log/file 2>&1
-
我们在写脚本时往往会使用相对路径,但是在crontab执行脚本时,由于工作目录不同,就会出现找不到文件或者目录不存在的问题。
解决方法是脚本中使用绝对路径或者在执行程序前切换工作目录,例如直接在crontab命令中切换工作目录:
0 12 * * * source $HOME/.bash_profile && cd $HOME/path/to/workdir && ./script > /HOME/log/file 2>&1
python – Django Celery Logging
在task.py 中:
from celery.utils.log import get_task_logger
logger = get_task_logger(__name__)
在settings.py 中设置
LOGGING = {
'version':1,
'disable_existing_loggers':False,
'formatters': {
'simple': {
'format': '%(asctime)s %(levelname)s [Line: %(lineno)s] -- %(message)s',
"datefmt": "%Y-%m-%d %H:%M:%S",
},
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'celery': {
'level': 'DEBUG',
'class': 'logging.handlers.FileHandler',
'filename': 'celery.log',
'formatter': 'simple',
'maxBytes': 1024 * 1024 * 100, # 100 mb
},
'django_crontab': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': 'django_crontab.log', //后台输出错误的详情会记录在该文件中
'formatter': 'simple'
},
},
'loggers': {
'apps_project.jcscantask.tasks': { //tasks.py 所在文件的路径
'handlers': ['celery', 'console'],
'level': 'DEBUG',
},
'django_crontab.crontab': {
'handlers': ['django_crontab'],
'level': 'DEBUG',
'propagate': True,
},
}
}
from logging.config import dictConfig
dictConfig(LOGGING)
django-warning
# project.urls
from django.conf.urls import url, include
import foo_app.urls
import foo_app.views
import bar_app.urls
urlpatterns = [
url(r'^$', include(foo_app.urls)),
url(r'^foo-app/', include(foo_app.urls)),
url(r'^bar-app/', include(bar_app.urls)),
]
warning ?: (urls.W001) Your URL pattern ‘^
′
u
s
e
s
i
n
c
l
u
d
e
w
i
t
h
a
r
e
g
e
x
e
n
d
i
n
g
w
i
t
h
a
′
' uses include with a regex ending with a '
′usesincludewitharegexendingwitha′’. Remove the dollar from the regex to avoid problems including URLs.
The fix
urlpatterns = [
url(r'^\Z', include(foo_app.urls)),
url(r^foo-app/', include(foo_app.urls)),
url(r^bar-app/', include(bar_app.urls)),
]
\Z 匹配的是整段输入,结尾终止子可有可无,不管在单行模式还是多行模式下
^ 和 $ 在单行模式下匹配整段输入
Django rest framework----分页
详见链接
request.POST与request.POST.get(request.GET与request.GET.get)的不同之处
首先,request.GET 和 request.POST是两个对象,类字典对象,提供和字典类似的接口
pageNumber = request.POST.get(‘pageNumber’,1)
从post中取得数据,如果不存在则默认值为1
pageNumber = request.GET.get(‘pageNumber’,1)
从get中寻找名为 pageNumber的GET参数,如果如果参数没有提交则默认值为1 ;这里的 get() 是每个python的的字典数据类型都有的方法。如果只是使用 request.GET[‘pageNumber’] 访问变量,在Get数据时 pageNumber 不可得,可能引发 KeyError 。
ORM简介
ORM是“对象-关系-映射”的简称,就是将对对象的操作映射为关系型数据库的语句
- 根据对象的类型生成表结构
- 将对对象、列表的操作,转换为SQL语句
- 将SQL查询到的结果转换为对象、列表
需要安装MySQL-python 或pymysql插件
字段属性被定义在django.db.models.fields目录下
字段类型:
BooleanField
AutoField:一个根据实际ID自动增长的IntegerField,通常不指定
CharField(max_length=字符长度)
TextField:大文本字段,一般超过4000使用
IntegerField
DecimalField(max_digits=None,decimal_places=None):使用python的Decimal实例表示的十进制浮点数
FloatField:使用python的float实例表示的浮点数
DateField(auto_now=False,auto_now_add=False):使用python的datetime.date实例表示的日期;auto_now每次保存对象时,自动设置该字段为当前时间,用于“最后一次修改”的时间戳,它总是使用当前时间;auto_now_add,对象第一次被创建时自动设置当前时间,用于创建的时间戳。使用这两个字段,就不能自己编辑时间
DateTimeField 、TimeField
FileField:一个上传文件的字段(其实就是一个字符串,文件存在的路径)
ImageField:继承了FileField的所有属性和方法(其实就是一个字符串,文件存在的路径)
**字段选项**
null :如果为true,django将空值NULL存储到数据库,默认为False
blank:如果为true,则该字段允许为空白,默认为false。null是数据库范畴的概念,blank是表单验证范畴的
db_column:字段的名称,如果未指定,则使用属性的名称
db_index:若为true,则在表中会为此字段创建索引
default : 默认值
primary_key :若为true,则成为主键
unique:若为true,则这个字段在表中有唯一值
**关系:**
关系的类型包括:
ForeignKey(一对多)
ManyToManyField
OneToOneField
例:BookInfo(一) HeroInfo(多) book=models.Foreikey(BookInfo)(其实,这里的book在BookInfo的表中对应的字段是book_id)
用一访问多:对象.模型类小写_set
HeroInfo 的对象:hero ,BookInfo对象book
book.heroinfo_set
hero.book(bero.book_id 或 hero.book.id)
用一访问一:对象.模型类小写
heroinfo.bookinfo
访问id:对象.属性_id
元选项
在模型类中定义:类Meta,用于设置元信息
元信息db_table :定义数据表名名称,推荐使用小写字母
ordering:对象的默认排序字段,获取对象的列表时使用,接收属性构成列表,排序会增加数据库的开销
class BookInfo(models.Model):
...
class Meta:
db_table="bookinfo"
ordering=['id','-time']
类的属性:
objects:是Manger类型的对象,用于与数据库进行交互
当定义模型类时,没有指定管理器,则django会为模型类提供一个名为objects的管理器objects=model.Manager()
管理器manager
管理器是Django的模型进行数据库的查询操作的接口,django应用中的每个模型都至少有一个管理器
自定义管理器主要用于两种情况:
情况一:向管理器中添加额外的方法
情况二:修改管理器返回的原始查询集:重写get_queryset()方法
class BookInfoManager(models.Manager):
def get_queryset(self):
return ...
django通过新建模型类完成和数据库表的一一对应,管理器是模型类的属性,通过使用管理器完成和数据库的交互。
模型查询
查询集的特点一:惰性查询
**返回查询集的方法:**
all()、filter()、exclude()、order_by()
values():一个对象构成一个字典,然后构成一个列表返回
**返回当单个值的方法:**
get():返回单个满足条件的对象,如未找到,则会引发模型类不存在的异常
count():返回当前查询集的总条数
first():返回第一个对象
last():
exists():判断查询集中是否有数据
**限制查询集**
查询集返回列表,可以使用下标的方式进行限制,等同于sql的limit和offset
**特性二:查询集的缓存:**
每个查询集都包含一个缓存来最小化对数据库的访问
在新建的查询集中,缓存为空,首次对查询集求值时,会发生数据库查询,django会将查询的结果存在查询集的缓存中,并返回请求的结果,接下来对查询集求值将重用缓存的结果
**聚合函数:**
1、使用aggregate()返回聚合函数的值
2、函数:Avg、Count、Max、Min、Sum
from django.db.models import Max
maxDate=list.aggregate(Max('pub_date'))(list是filter后的结果)
**F对象**
1、可以使用模型的字段A与字段B进行比较,如果A写在了等号的左边,则B出现在等号的右边,需要通过F对象构造
list.filter(bread__gte=F('bcoment'))
2、django支持对F()对象使用算数运算
list.filter(bread__gte=F('bcoment')*2)
3、对于date/time字段,可与timedelta()进行运算
list.filter(pub_date__lte=F('pub_date')+timedelta(days=1))
**Q对象**
1、过滤器的方法中关键字参数查询,会合并成and进行
2、需要进行or查询,使用Q对象
3、Q对象(django.db.models.Q)用于封装一组关键字参数,这些关键字参数与“比较运算符”中的相同
list.filter(Q(pk__lt=6)|Q(comment__gt=19)&Q(...))
not 操作
list.filter(~Q(...))
可以使用& | ~结合括号进行分组,构造复杂的Q对象
过滤器参数 可以混合使用Q对象和关键字参数,所有参数都将and在一起,Q对象必须位于关键字参数的前面
批量录入数据:
querysetlist=[]
for i in resultlist:
querysetlist.append(Account(name=i))
Account.objects.bulk_create(querysetlist)
视图
404视图
- defaults.page_not_found(request,template_name=‘404.html’)
- 默认的404视图将传递一个变量给模板:request_path,它是导致错误的URL
- 如果django在检测URLconf 中的每个正则表达式后没有找到匹配的内容也将调用404视图
- 如果在settings中DEBUG设置为TRUE,那么将永远不会调用404视图,而是显示URLconf 并带有一些调试信息
- 在templates中创建404.html
- 在settings中设置:DEBUG=False
HTTPRequest对象
- 服务器接收到http协议的请求后,会根据报文创建httprequest对象
- 视图函数的第一个参数是httprequest对象
- 在django.http模块中定义了httprequest对象的api
属性(除了特别说明,都是只读的)
(1)path:一个字符串,表示请求的页面的完整路径,不包含域名
(2)method:一个字符串,表示请求使用的http方法,常用值包括:GET、POST
(3)encoding:一个字符串,表示提交的数据的编码方式,若为None则表示使用浏览器的默认是设置,一般为utf-8。这个属性是可写的,可以通过修改它来修改表单使用的编码,接下来对属性的任何访问将使用新的encoding 值
(4)GET:一个类似于字典的对象,包含get请求方式的所有参数
(5)POST:一个类似于字典的对象,包含post请求方式的所有参数
(6)FILES:一个类似于字典的对象,包含所有的上传文件
(7)COOKIES:一个标准的python字典,包含所有的cookie
(8)session:一个既可读you可写的类似于字典的对象,表示当前的会话,只有当django启用会话的支持时才可用.
类似于字典对象是QueryDict对象:
(1)定义在django.http.QueryDict
(2)与python字典不同,QueryDict类型的对象用来处理同一键带有多值的情况
(3)方法get:只能获取键的一个值,若存在多个值,则获取最后一个。dict.get(“键”,default)或dict[‘键’]
(4)方法:getlist():将键的值以列表的方式返回,可以获取一个键的多个值,dict.getlist(‘键’,default)
注: 在django中在一个页面的html中写表示会从网站的根目录进行查找(www.itcast.cn/a.html)<a=href=‘a.html’>表示会从当前页的目录查找(www.itcast.cn/a/a.html) <a =href=’?a=1’>表示路径为(www.itcast.cn/a/a.html/?a=1)
方法
(1)is_ajax():如果请求是通过XMLHttpRequest发起的,则返回True
状态保持
(1)实现状态保持的方式:在客户端或服务器端存储与会话有关的数据
(2)客户端与服务器端的一次通信,就是一次会话
(3)存储方式包括cookie、session,会话一般是指session对象
(4)使用cookie,所有数据存在客户端,注意不要存敏感信息
(5)推荐使用session方式,所有数据存储在服务端,在客户端cookie中存储session_id
(6)状态保持的目的是在一段时间内跟踪请求者的状态,可以实现跨页面访问当前请求者的数据
启用session
(1)在settings.py 文件:installed_apps中添加:django.contrib.sessions;在middleware_classes中添加:django.contrib.sessions.middleware.SessionMiddleware
使用session
(2)启动会话后,每个httpRequest对象将具有一个session属性,是一个类字典对象。
注:添加成功后,会自动生成django_session的表
(3)get(key,default):根据键获取会话的值
(4)clear():清除所有的会话
(5)flush():删除当前会话数据并删除会话的cookie
(6)del request.session[key]删除会话
遇到的问题汇总
- django.db.utils.IntegrityError: (1215, ‘Cannot add foreign key constraint’)
解决方法:删除数据表,包括包括migration中的迁移文件,数据表django_migration 中的创建记录,然后重新生成即可。