class BookInfoManager(models.Manager): def get_queryset(self): return super(BookInfoManager, self).get_queryset().filter(isDelete=False) class BookInfo(models.Model): ... books = BookInfoManager()123456
23 、创建对象
说明: _init _方法已经在基类models.Model中使用,在自定义模型中无法使用,
方式一:在模型类中增加一个类方法
class BookInfo(models.Model): ... @classmethod def create(cls, title, pub_date): book = cls(btitle=title, bpub_date=pub_date) book.isDelete = False return book 引入时间包:from datetime import * 调用:book=BookInfo.create("hello",datetime(1980,10,11)); 保存:book.save()12345678910
方式二:在自定义管理器中添加一个方法
在管理器的方法中,可以通过self.model来得到它所属的模型类
class BookInfoManager(models.Manager): def create_book(self, title, pub_date): book = self.model() book.btitle = title book.bpub_date = pub_date book.isDelete = False return book
class BookInfo(models.Model): ... books = BookInfoManager() 调用:book=BookInfo.books.create_book("abc",datetime(1980,1,1)) 保存:book.save()12345678910111213
def upload(request): if request.method == "POST": f1 = request.FILES['pic'] fname = '%s/cars/%s' % (settings.MEDIA_ROOT,f1.name) with open(fname, 'w') as pic: for c in f1.chunks(): pic.write(c) return HttpResponse("ok") else: return HttpResponse("error")123456789101112
def getArea1(request): list = AreaInfo.objects.filter(aPArea__isnull=True) list2 = [] for a in list: list2.append([a.aid, a.atitle]) return JsonResponse({'data': list2})
def getArea2(request, pid): list = AreaInfo.objects.filter(aPArea_id=pid) list2 = [] for a in list: list2.append({'id': a.aid, 'title': a.atitle}) return JsonResponse({'data': list2})1234567891011121314151617181920
在urls.py中配置urlconf
from django.conf.urls import url from . import views
双击打开pycharm开发工具,点击File菜单,选择Settings,安装django
再次点击File--->New Project,选择Django,配置编译器
创建完毕框架项目,可以查看到项目结构,以及配置文件
打开amn文件夹下的setting.py,查看INSTALLED_APPS配置
点击右上角的Edit Configuration,配置运行相关的属性
检查发现,新建的django项目,重新打开窗口,需要重新安装django
双击打开pycharm开发工具,点击File菜单,选择Settings,安装django
再次点击File--->New Project,选择Django,配置编译器
创建完毕框架项目,可以查看到项目结构,以及配置文件
打开amn文件夹下的setting.py,查看INSTALLED_APPS配置
点击右上角的Edit Configuration,配置运行相关的属性
检查发现,新建的django项目,重新打开窗口,需要重新安装django
双击打开pycharm开发工具,点击File菜单,选择Settings,安装django
再次点击File--->New Project,选择Django,配置编译器
创建完毕框架项目,可以查看到项目结构,以及配置文件
打开amn文件夹下的setting.py,查看INSTALLED_APPS配置
点击右上角的Edit Configuration,配置运行相关的属性
检查发现,新建的django项目,重新打开窗口,需要重新安装django
Django 作为一个杰出的Python开源框架,或许得不到和其它流行框架如Rails这样多的赞美,但是它和其他框架一样精炼,非常注重DRY(Don't Repeat Yoursef)原则、组件的重用性,通过自动化过程使编码更简洁。
如果在Django项目中能够灵活使用某些方法和技巧的话,它将大大加快软件开发的速度同时避免很多头疼的事。作者在下面列举了几点,这些方法由浅入深,可以帮助任何级别的程序员更加熟练的使用Django。
1、 使用{%url%}标签
尽可能使用向后兼容的{%url%}标签来替换硬编码形式的href,与使用绝对路径的url(当然最好不要这样做) 一样达到相同的效果。你的Django项目迁移起来,那些链接也不会有影响。(译者注:比如说我们有一个views.about函数指向about页面r'^about/$',就可以{% url views.about as about_url %}然后用{{about_url}}这个变量来代替绝对URL地址)尽管它还不是最高级的技巧,但是它确实值得你应用于Django项目中。
2、 尝试把Django admin应用到PHP项目中
Django最伟大的特性之一就是已经成为Django的核心功能的用户验证系统。它易安装,主要用于用户认证和其它一些必要的配置。这个酷毙了的用户系统甚至被建议应用到你的PHP项目中去,这里有一边Jeff Croft 关于为什么Django能够作为任何语言任何应用中的系统管理模块的一个很好的解决方案。
3、 使用独立的媒体服务器
在开发环境中把静态文件放在与Django项目所在的同一台服务器中问题并不大,但是却不要使用在生产环境中,为什么?效率问题。Jacobian.org给出了一个合理的解释。通过一台独立的服务器来处理静态文件,性能将得到有效的提升,如果不想买服务器的话,那么使用Amazon S3相对来更便宜。
4、 使用Debugger工具条
调试工具对任何一种语言来说都是不可或缺的.他们能够加快开发的速度,指出潜在的缺陷. Rob Hudson开发了一个对开发人员非常有用django调试工具。
5、 使用Django单元测试
利用单元测试确保你代码的改变和预期的一样,而不会破坏任何老的代码,以便向后兼容。Django一个强大的特性就是他能极其简单地写单元测试。Django也可直接使用python的文本测试和单元测试。Django的文档提供了一个详细的教程和样例代码关于怎样做单元测试使得代码正确地运行,以及去除讨厌的bug
6、 使用速查卡
这里有两页厚的速查卡,在 Django文档中你可能翻来覆去要找半天的东西在这里一目了然。它包含如下几个主题
模板:
模板标签及可选项
模板过滤器及可选项
日期格式化语法快速查阅
模型:
域和及选项
常用域的可选项
元类型可选项
模型管理可选项
表单:
域和可选项
常用域可选项
标准错误消息键值
7、使用Django-chunks
除了使用Django的富文本编辑器创建块更容易之外,Django-chunks同样是用于模板中,这是重用代码块的必不可少的工具。
8、 使用Memcache
如果性能在你的Django项目中已经成为一个棘手的问题,那么你将需要使用一些缓存策略。然而Django为缓存提供很多的选择。目前最好的无疑是Memcache,用Django安装memcache非常地简单,如果你使用cmemcache模块的时候。只要模块安装完成后,你仅仅修改一行配置项,你的Django页面变得轻快起来。
Python创建 Django 项目有三种方式,常见的方式是在 cmd 中输入以下命令创建,然后在 Pycharm 中打开此项目目录。
1、安装Django
pip install django1
2、创建Django项目
django-admin startproject 项目名称1
3、在setting文件中配置数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '',
'USER':'root',
'PASSWORD':'',
'HOST':'',
'PORT':'',
}
}12345678910
4、创建应用
python manage.py startapp 应用名称1
5、定义模型类models.py,一个类对应数据库的一个表,一个属性,对应数据表中的一个字段
from django.db import models
class 类名(models.Model):
xxxx=models.CharField(max_length=20)
。。。12345
6、生成数据表
激活模型:编辑settings.py文件,将应用加入到installed_apps中
生成迁移文件:根据模型类生成sql语句
python manage.py makemigrations
执行迁移:执行sql语句生成数据表
python manage.py migrate
7、运行Django项目,默认端口8000
python manage.py runserver ip:port1
8、使用Django的管理
创建一个管理员用户
python manage.py createsuperuser,按提示输入用户名、邮箱、密码1
启动服务器,通过“127.0.0.1:8000/admin”访问,输入上面创建的用户名、密码完成登录
进入管理站点,默认可以对groups、users进行管理
9、管理界面本地化
编辑settings.py文件,设置编码、时区
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'12
10、向admin注册应用的模型
打开admin.py文件,注册模型
from django.contrib import admin
from models import xxx
admin.site.register(xxx)
11、视图
在django中,视图对WEB请求进行回应
视图接收reqeust对象作为第一个参数,包含了请求的信息
视图就是一个Python函数,被定义在views.py中
#coding:utf-8
from django.http import HttpResponse
def index(request):
return HttpResponse("index")12345
定义完成视图后,需要配置urlconf,否则无法处理请求
12、模板
模板是html页面,可以根据视图中传递的数据填充值
修改settings.py文件,设置TEMPLATES的DIRS值
'DIRS': [os.path.join(BASE_DIR, 'templates')],1
在模板中访问视图传递的数据
{{输出值,可以是变量,也可以是对象.属性}}
{%执行代码段%}12
{{xxx}}
1234567891011
13、使用模板
编辑views.py文件,在方法中调用模板
from django.http import HttpResponse
from django.template import RequestContext, loader
from models import xxx
def index(request):
booklist = BookInfo.objects.all()
template = loader.get_template('xxx.html')
context = RequestContext(request, {'xxx': xxx})
return HttpResponse(template.render(context))
def detail(reqeust, id):
xxx = BookInfo.objects.get(pk=id)
template = loader.get_template(xxx.html')
context = RequestContext(reqeust, {'xxx': xxx})
return HttpResponse(template.render(context))123456789101112131415
14、Render
Django提供了函数Render()简化视图调用模板、构造上下文
from django.shortcuts import render
from models import xxx
def index(reqeust):
xxx = xxx.objects.all()
return render(reqeust, 'xxxx.html', {'xxx': xxx})
def detail(reqeust, id):
xxx = xxx.objects.get(pk=id)
return render(reqeust, 'xxx.html', {'xxx': xxx})1234567891011
15、ORM简介
MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库
ORM是“对象-关系-映射”的简称,主要任务是:
根据对象的类型生成表结构
将对象、列表的操作,转换为sql语句
将sql查询到的结果转换为对象、列表
这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动
Django中的模型包含存储数据的字段和约束,对应着数据库中唯一的表
16、使用MySql数据库
安装mysql包
pip install mysql-python1
在mysql中创建数据库
create databases 数据库名字 charset=utf81
打开settings.py文件,修改DATABASES项
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'xxx',
'USER': '用户名',
'PASSWORD': '密码',
'HOST': '数据库服务器ip,本地可以使用localhost',
'PORT': '端口,默认为3306',
}
}12345678910
17、开发流程
在models.py中定义模型类,要求继承自models.Model
把应用加入settings.py文件的installed_app项
生成迁移文件
执行迁移生成表
使用模型类进行crud操作
18、使用数据库生成模型类
python manage.py inspectdb > xxx/models.py1
19、定义模型
在模型中定义属性,会生成表中的字段
django会为表增加自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后,则django不会再生成默认的主键列
属性命名限制
& 不能是python的保留关键字
& 由于django的查询方式,不允许使用连续的下划线
20、定义属性
对于重要数据都做逻辑删除,不做物理删除,实现方法是定义isDelete属性,类型为BooleanField,默认值为False
21、元选项
在模型类中定义类Meta,用于设置元信息
元信息db_table:定义数据表名称,推荐使用小写字母,数据表的默认名称
ordering:对象的默认排序字段,获取对象的列表时使用,接收属性构成的列表
class BookInfo(models.Model):
...
class Meta():
ordering = ['id']1234
字符串前加-表示倒序,不加-表示正序
class BookInfo(models.Model):
...
class Meta():
ordering = ['-id']1234
排序会增加数据库的开销
22、管理器Manager
用于与数据库进行交互
当定义模型类时没有指定管理器,则Django会为模型类提供一个名为objects的管理器
支持明确指定模型类的管理器
当为模型类指定管理器后,django不再为模型类生成名为objects的默认管理器
管理器是Django的模型进行数据库的查询操作的接口,Django应用的每个模型都拥有至少一个管理器
自定义管理器类主要用于两种情况
情况一:向管理器类中添加额外的方法
情况二:修改管理器返回的原始查询集:重写get_queryset()方法
class BookInfoManager(models.Manager):
def get_queryset(self):
return super(BookInfoManager, self).get_queryset().filter(isDelete=False)
class BookInfo(models.Model):
...
books = BookInfoManager()123456
23 、创建对象
说明: _init _方法已经在基类models.Model中使用,在自定义模型中无法使用,
方式一:在模型类中增加一个类方法
class BookInfo(models.Model):
...
@classmethod
def create(cls, title, pub_date):
book = cls(btitle=title, bpub_date=pub_date)
book.isDelete = False
return book
引入时间包:from datetime import *
调用:book=BookInfo.create("hello",datetime(1980,10,11));
保存:book.save()12345678910
方式二:在自定义管理器中添加一个方法
在管理器的方法中,可以通过self.model来得到它所属的模型类
class BookInfoManager(models.Manager):
def create_book(self, title, pub_date):
book = self.model()
book.btitle = title
book.bpub_date = pub_date
book.isDelete = False
return book
class BookInfo(models.Model):
...
books = BookInfoManager()
调用:book=BookInfo.books.create_book("abc",datetime(1980,1,1))
保存:book.save()12345678910111213
24、实例的属性
DoesNotExist:在进行单个查询时,模型的对象不存在时会引发此异常,结合try/except使用
25、实例的方法
str (self):重写object方法,此方法在将对象转换成字符串时会被调用
save():将模型对象保存到数据表中
delete():将模型对象从数据表中删除
26、查询集
在管理器上调用过滤器方法会返回查询集
查询集经过过滤器筛选后返回新的查询集,因此可以写成链式过滤
惰性执行:创建查询集不会带来任何数据库的访问,直到调用数据时,才会访问数据库
何时对查询集求值:迭代,序列化,与if合用
返回查询集的方法,称为过滤器
all()
filter()
exclude()
order_by()
values():一个对象构成一个字典,然后构成一个列表返回
写法:
filter(键1=值1,键2=值2)
等价于
filter(键1=值1).filter(键2=值2)123
返回单个值的方法
get():返回单个满足条件的对象
如果未找到会引发"模型类.DoesNotExist"异常
如果多条被返回,会引发"模型类.MultipleObjectsReturned"异常
count():返回当前查询的总条数
first():返回第一个对象
last():返回最后一个对象
exists():判断查询集中是否有数据,如果有则返回True
26、限制查询集
查询集返回列表,可以使用下标的方式进行限制,等同于sql中的limit和offset子句
注意:不支持负数索引
使用下标后返回一个新的查询集,不会立即执行查询
如果获取一个对象,直接使用[0],等同于[0:1].get(),但是如果没有数据,[0]引发IndexError异常,[0:1].get()引发DoesNotExist异常
27、查询集的缓存
每个查询集都包含一个缓存来最小化对数据库的访问
在新建的查询集中,缓存为空,首次对查询集求值时,会发生数据库查询,django会将查询的结果存在查询集的缓存中,并返回请求的结果,接下来对查询集求值将重用缓存的结果
情况一:这构成了两个查询集,无法重用缓存,每次查询都会与数据库进行一次交互,增加了数据库的负载
print([e.title for e in Entry.objects.all()])
print([e.title for e in Entry.objects.all()])12
情况二:两次循环使用同一个查询集,第二次使用缓存中的数据
querylist=Entry.objects.all()
print([e.title for e in querylist])
print([e.title for e in querylist])123
何时查询集不会被缓存:当只对查询集的部分进行求值时会检查缓存,但是如果这部分不在缓存中,那么接下来查询返回的记录将不会被缓存,这意味着使用索引来限制查询集将不会填充缓存,如果这部分数据已经被缓存,则直接使用缓存中的数据
28、字段查询
实现where子名,作为方法filter()、exclude()、get()的参数
语法:属性名称__比较运算符=值
表示两个下划线,左侧是属性名称,右侧是比较类型
对于外键,使用“属性名_id”表示外键的原始值
转义:like语句中使用了%与,匹配数据中的%与,在过滤器中直接写,例如:
filter(title__contains="%")=>where title like ‘%%%’,表示查找标题中包含%的
比较运算符
exact:表示判等,大小写敏感;如果没有写“ 比较运算符”,表示判等
filter(isDelete=False)
contains:是否包含,大小写敏感
exclude(btitle__contains='传')
startswith、endswith:以value开头或结尾,大小写敏感
exclude(btitle__endswith='传')
isnull、isnotnull:是否为null
filter(btitle__isnull=False)
在前面加个i表示不区分大小写,如iexact、icontains、istarswith、iendswith
in:是否包含在范围内
filter(pk__in=[1, 2, 3, 4, 5])
gt、gte、lt、lte:大于、大于等于、小于、小于等于
filter(id__gt=3)
year、month、day、week_day、hour、minute、second:对日期间类型的属性进行运算
filter(bpub_date__year=1980)
filter(bpub_date__gt=date(1980, 12, 31))
跨关联关系的查询:处理join查询
– 语法:模型类名 <属性名> <比较>
– 注:可以没有__<比较>部分,表示等于,结果同inner join
– 可返向使用,即在关联的两个模型中都可以使用
filter(heroinfo_ _hcontent_ _contains='八')
查询的快捷方式:pk,pk表示primary key,默认的主键是id
filter(pk__lt=6)
聚合函数
使用aggregate()函数返回聚合函数的值
函数:Avg,Count,Max,Min,Sum
from django.db.models import Max
maxDate = list.aggregate(Max('bpub_date'))12
count的一般用法:
count = list.count()
F对象
可以使用模型的字段A与字段B进行比较,如果A写在了等号的左边,则B出现在等号的右边,需要通过F对象构造
list.filter(bread__gte=F('bcommet'))
django支持对F()对象使用算数运算
list.filter(bread__gte=F('bcommet') * 2)
F()对象中还可以写作“模型类__列名”进行关联查询
list.filter(isDelete=F('heroinfo__isDelete'))
对于date/time字段,可与timedelta()进行运算
list.filter(bpub_date__lt=F('bpub_date') + timedelta(days=1))
Q对象
过滤器的方法中关键字参数查询,会合并为And进行
需要进行or查询,使用Q()对象
Q对象(django.db.models.Q)用于封装一组关键字参数,这些关键字参数与“比较运算符”中的相同
from django.db.models import Q
list.filter(Q(pk_ _lt=6))12
Q对象可以使用&(and)、|(or)操作符组合起来
当操作符应用在两个Q对象时,会产生一个新的Q对象
list.filter(pk_ _lt=6).filter(bcommet_ _gt=10)
list.filter(Q(pk_ _lt=6) | Q(bcommet_ _gt=10))12
使用~(not)操作符在Q对象前表示取反
list.filter(~Q(pk__lt=6))
可以使用&|~结合括号进行分组,构造做生意复杂的Q对象
过滤器函数可以传递一个或多个Q对象作为位置参数,如果有多个Q对象,这些参数的逻辑为and
过滤器函数可以混合使用Q对象和关键字参数,所有参数都将and在一起,Q对象必须位于关键字参数的前面
29、错误视图
Django原生自带几个默认视图用于处理HTTP错误
404 (page not found) 视图
defaults.page_not_found(request, template_name=‘404.html’)
默认的404视图将传递一个变量给模板:request_path,它是导致错误的URL
如果Django在检测URLconf中的每个正则表达式后没有找到匹配的内容也将调用404视图
如果在settings中DEBUG设置为True,那么将永远不会调用404视图,而是显示URLconf 并带有一些调试信息
在templates中创建404.html
找不到了
{{request_path}}
1234567891011
在settings.py中修改调试
DEBUG = False
ALLOWED_HOSTS = ['*', ]12
30、HttpReqeust对象
is_ajax():如果请求是通过XMLHttpRequest发起的,则返回True
31、QueryDict对象
定义在django.http.QueryDict
request对象的属性GET、POST都是QueryDict类型的对象
与python字典不同,QueryDict类型的对象用来处理同一个键带有多个值的情况
方法get():根据键获取值
– 只能获取键的一个值
如果一个键同时拥有多个值,获取最后一个值
dict.get('键',default)
或简写为
dict['键']
方法getlist():根据键获取值
– 将键的值以列表返回,可以获取一个键的多个值
– dict.getlist(‘键’,default)
31、HttpResponse对象
在django.http模块中定义了HttpResponse对象的API
HttpRequest对象由Django自动创建,HttpResponse对象由程序员创建
不调用模板,直接返回数据
– 调用模板
from django.http import HttpResponse
from django.template import RequestContext, loader
def index(request):
t1 = loader.get_template('polls/index.html')
context = RequestContext(request, {'h1': 'hello'})
return HttpResponse(t1.render(context))1234567
32、HttpResponseRedirect
重定向,服务器端跳转
构造函数的第一个参数用来指定重定向的地址
33、JsonResponse
返回json数据,一般用于异步请求
_init _(data)
帮助用户创建JSON编码的响应
参数data是字典对象
sonResponse的默认Content-Type为application/json
from django.http import JsonResponse
def index2(requeset):
return JsonResponse({'list': 'abc'})1234
34、启用session
使用django-admin startproject创建的项目默认启用
在settings.py文件中
项INSTALLED_APPS列表中添加:
'django.contrib.sessions',
项MIDDLEWARE_CLASSES列表中添加:
'django.contrib.sessions.middleware.SessionMiddleware',12345
禁用会话:删除上面指定的两个值,禁用会话将节省一些性能消耗
启用会话后,每个HttpRequest对象将具有一个session属性,它是一个类字典对象
get(key, default=None):根据键获取会话的值
clear():清除所有会话
flush():删除当前的会话数据并删除会话的Cookie
del request.session[‘member_id’]:删除会话
35、会话过期时间
set_expiry(value):设置会话的超时时间
如果没有指定,则两个星期后过期
如果value是一个整数,会话将在values秒没有活动后过期
若果value是一个imedelta对象,会话将在当前时间加上这个指定的日期/时间过期
如果value为0,那么用户会话的Cookie将在用户的浏览器关闭时过期
如果value为None,那么会话永不过期
修改视图中login_handle函数,查看效果
存储session
使用存储会话的方式,可以使用settings.py的SESSION_ENGINE项指定
基于数据库的会话:这是django默认的会话存储方式,需要添加django.contrib.sessions到的INSTALLED_APPS设置中,运行manage.py migrate在数据库中安装会话表,可显示指定为
SESSION_ENGINE='django.contrib.sessions.backends.db'12
基于缓存的会话:只存在本地内在中,如果丢失则不能找回,比数据库的方式读写更快
SESSION_ENGINE='django.contrib.sessions.backends.cache'12
可以将缓存和数据库同时使用:优先从本地缓存中获取,如果没有则从数据库中获取
SESSION_ENGINE='django.contrib.sessions.backends.cached_db'123
使用Redis缓存session
会话还支持文件、纯cookie、Memcached、Redis等方式存储,下面演示使用redis存储
安装包
pip install django-redis-sessions1
修改settings中的配置,增加如下项
SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_HOST = 'localhost'
SESSION_REDIS_PORT = 6379
SESSION_REDIS_DB = 0
SESSION_REDIS_PASSWORD = ''
SESSION_REDIS_PREFIX = 'session'123456
管理redis的命令
启动:sudo redis-server /etc/redis/redis.conf
停止:sudo redis-server stop
重启:sudo redis-server restart
redis-cli:使用客户端连接服务器
keys *:查看所有的键
get name:获取指定键的值
del name:删除指定名称的键1234567
36、模板
定义模板路径
DIRS=[os.path.join(BASE_DIR,"templates")]1
模板处理
Django处理模板分为两个阶段
Step1 加载:根据给定的标识找到模板然后预处理,通常会将它编译好放在内存中
loader.get_template(template_name),返回一个Template对象1
Step2 渲染:使用Context数据对模板插值并返回生成的字符串
Template对象的render(RequestContext)方法,使用context渲染模板1
加载渲染完整代码:
from django.template import loader, RequestContext
from django.http import HttpResponse
def index(request):
tem = loader.get_template('temtest/index.html')
context = RequestContext(request, {})
return HttpResponse(tem.render(context))12345678
快捷函数
为了减少加载模板、渲染模板的重复代码,django提供了快捷函数
render_to_string("")
render(request,‘模板’,context)
from django.shortcuts import render
def index(request):
return render(request, 'temtest/index.html')12345
csrf_token:这个标签用于跨站请求伪造保护
{ % csrf_token %}1
过滤器
语法:{ { 变量|过滤器 }},例如{ { name|lower }},表示将变量name的值变为小写输出
37、HTML转义
关闭转义
对于变量使用safe过滤器
{{ data|safe }}1
对于代码块使用autoescape标签
{ % autoescape off %}
{{ body }}
{ % endautoescape %}123
标签autoescape接受on或者off参数
自动转义标签在base模板中关闭,在child模板中也是关闭的
38、csrf
跨站请求伪造
某些恶意网站上包含链接、表单按钮或者JavaScript,它们会利用登录过的用户在浏览器中的认证信息试图在你的网站上完成某些操作,这就是跨站攻击
防csrf的使用
在django的模板中,提供了防止跨站攻击的方法,使用步骤如下:
step1:在settings.py中启用’django.middleware.csrf.CsrfViewMiddleware’中间件,此项在创建项目时,默认被启用
step2:在csrf1.html中添加标签
1234
取消保护
如果某些视图不需要保护,可以使用装饰器csrf_exempt,模板中也不需要写标签,修改csrf2的视图如下
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def csrf2(request):
uname=request.POST['uname']
return render(request,'booktest/csrf2.html',{'uname':uname})123456
39、验证码
验证码视图
新建viewsUtil.py,定义函数verifycode
此段代码用到了PIL中的Image、ImageDraw、ImageFont模块,需要先安装Pillow(3.4.1)包
Image表示画布对象
ImageDraw表示画笔对象
ImageFont表示字体对象,ubuntu的字体路径为“/usr/share/fonts/truetype/freefont”
代码如下:
from django.http import HttpResponse
def verifycode(request):
#引入绘图模块
from PIL import Image, ImageDraw, ImageFont
#引入随机函数模块
import random
#定义变量,用于画面的背景色、宽、高
bgcolor = (random.randrange(20, 100), random.randrange(
20, 100), 255)
width = 100
height = 25
#创建画面对象
im = Image.new('RGB', (width, height), bgcolor)
#创建画笔对象
draw = ImageDraw.Draw(im)
#调用画笔的point()函数绘制噪点
for i in range(0, 100):
xy = (random.randrange(0, width), random.randrange(0, height))
fill = (random.randrange(0, 255), 255, random.randrange(0, 255))
draw.point(xy, fill=fill)
#定义验证码的备选值
str1 = 'ABCD123EFGHIJK456LMNOPQRS789TUVWXYZ0'
#随机选取4个值作为验证码
rand_str = ''
for i in range(0, 4):
rand_str += str1[random.randrange(0, len(str1))]
#构造字体对象
font = ImageFont.truetype('FreeMono.ttf', 23)
#构造字体颜色
fontcolor = (255, random.randrange(0, 255), random.randrange(0, 255))
#绘制4个字
draw.text((5, 2), rand_str[0], font=font, fill=fontcolor)
draw.text((25, 2), rand_str[1], font=font, fill=fontcolor)
draw.text((50, 2), rand_str[2], font=font, fill=fontcolor)
draw.text((75, 2), rand_str[3], font=font, fill=fontcolor)
#释放画笔
del draw
#存入session,用于做进一步验证
request.session['verifycode'] = rand_str
#内存文件操作
import cStringIO
buf = cStringIO.StringIO()
#将图片保存在内存中,文件类型为png
im.save(buf, 'png')
#将内存中的图片数据返回给客户端,MIME类型为图片png
return HttpResponse(buf.getvalue(), 'image/png')1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
配置url
在urls.py中定义请求验证码视图的url
from . import viewsUtil
urlpatterns = [
url(r'^verifycode/$', viewsUtil.verifycode),
]12345
显示验证码
在模板中使用img标签,src指向验证码视图
1
40、管理静态文件
配置静态文件
在settings 文件中定义静态内容
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]1234
在项目根目录下创建static目录,再创建当前应用名称的目录
在模板中可以使用硬编码
/static/xxx/xxxx.jpg1
在模板中可以使用static编码
{ % load static from staticfiles %}
12
41、中间件
是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出
激活:添加到Django配置文件中的MIDDLEWARE_CLASSES元组中
每个中间件组件是一个独立的Python类,可以定义下面方法中的一个或多个
_init _:无需任何参数,服务器响应第一个请求的时候调用一次,用于确定是否启用当前中间件
process_request(request):执行视图之前被调用,在每个请求上调用,返回None或HttpResponse对象
process_view(request, view_func, view_args, view_kwargs):调用视图之前被调用,在每个请求上调用,返回None或HttpResponse对象
process_template_response(request, response):在视图刚好执行完毕之后被调用,在每个请求上调用,返回实现了render方法的响应对象
process_response(request, response):所有响应返回浏览器之前被调用,在每个请求上调用,返回HttpResponse对象
process_exception(request,response,exception):当视图抛出异常时调用,在每个请求上调用,返回一个HttpResponse对象
使用中间件,可以干扰整个处理过程,每次请求中都会执行中间件的这个方法
示例:自定义异常处理
与settings.py同级目录下创建myexception.py文件,定义类MyException,实现process_exception方法
from django.http import HttpResponse
class MyException():
def process_exception(request,response, exception):
return HttpResponse(exception.message)1234
将类MyException注册到settings.py中间件中
MIDDLEWARE_CLASSES = (
'test1.myexception.MyException',
...
)1234
定义视图,并发生一个异常信息,则会运行自定义的异常处理
42、上传图片
当Django在处理文件上传的时候,文件数据被保存在request.FILES
FILES中的每个键为中的name
注意:FILES只有在请求的方法为POST 且提交的带有enctype=“multipart/form-data” 的情况下才会包含数据。否则,FILES 将为一个空的类似于字典的对象
使用模型处理上传文件:将属性定义成models.ImageField类型
pic=models.ImageField(upload_to='cars/')1
注意:如果属性类型为ImageField需要安装包Pilow
pip install Pillow==3.4.11
图片存储路径
在项目根目录下创建media文件夹
图片上传后,会被保存到“/static/media/cars/图片文件”
打开settings.py文件,增加media_root项
MEDIA_ROOT=os.path.join(BASE_DIR,"static/media")1
使用django后台管理,遇到ImageField类型的属性会出现一个file框,完成文件上传
手动上传的模板代码
123456789101112
手动上传的视图代码
from django.conf import settings
def upload(request):
if request.method == "POST":
f1 = request.FILES['pic']
fname = '%s/cars/%s' % (settings.MEDIA_ROOT,f1.name)
with open(fname, 'w') as pic:
for c in f1.chunks():
pic.write(c)
return HttpResponse("ok")
else:
return HttpResponse("error")123456789101112
43、Admin站点
通过使用startproject创建的项目模版中,默认Admin被启用
1.创建管理员的用户名和密码
python manage.py createsuperuser
然后按提示填写用户名、邮箱、密码12
2.在应用内admin.py文件完成注册,就可以在后台管理中维护模型的数据
from django.contrib import admin
from models import *
admin.site.register(HeroInfo)1234
查找admin文件:在INSTALLED_APPS项中加入django.contrib.admin,Django就会自动搜索每个应用的admin模块并将其导入
ModelAdmin对象
ModelAdmin类是模型在Admin界面中的表示形式
定义:定义一个类,继承于admin.ModelAdmin,注册模型时使用这个类
class HeroAdmin(admin.ModelAdmin):
...12
通常定义在应用的admin.py文件里
使用方式一:注册参数
admin.site.register(HeroInfo,HeroAdmin)1
使用方式二:注册装饰器
@admin.register(HeroInfo)
class HeroAdmin(admin.ModelAdmin):12
通过重写admin.ModelAdmin的属性规定显示效果,属性主要分为列表页、增加修改页两部分
列表页选项
“操作选项”的位置
actions_on_top、actions_on_bottom:默认显示在页面的顶部
class HeroAdmin(admin.ModelAdmin):
actions_on_top = True
actions_on_bottom = True123
list_display
出现列表中显示的字段
列表类型
在列表中,可以是字段名称,也可以是方法名称,但是方法名称默认不能排序
在方法中可以使用format_html()输出html内容
在models.py文件中
from django.db import models
from tinymce.models import HTMLField
from django.utils.html import format_html
class HeroInfo(models.Model):
hname = models.CharField(max_length=10)
hcontent = HTMLField()
isDelete = models.BooleanField()
def hContent(self):
return format_html(self.hcontent)
在admin.py文件中
class HeroAdmin(admin.ModelAdmin):
list_display = ['hname', 'hContent']123456789101112131415
让方法排序,为方法指定admin_order_field属性
在models.py中HeroInfo类的代码改为如下:
def hContent(self):
return format_html(self.hcontent)
hContent.admin_order_field = 'hname'1234
标题栏名称:将字段封装成方法,为方法设置short_description属性
在models.py中HeroInfo类的代码改为如下:
def hContent(self):
return format_html(self.hcontent)
hContent.admin_order_field = 'hname'1234
标题栏名称:将字段封装成方法,为方法设置short_description属性
在models.py中为HeroInfo类增加方法hName:
def hName(self):
return self.hname
hName.short_description = '姓名'
hContent.short_description = '内容'
在admin.py页中注册
class HeroAdmin(admin.ModelAdmin):
list_display = ['hName', 'hContent']123456789
list_filter
右侧栏过滤器,对哪些属性的值进行过滤
列表类型
只能接收字段
class HeroAdmin(admin.ModelAdmin):
...
list_filter = ['hname', 'hcontent']123
list_per_page
每页中显示多少项,默认设置为100
class HeroAdmin(admin.ModelAdmin):
...
list_per_page = 10123
search_fields
搜索框
列表类型,表示在这些字段上进行搜索
只能接收字段
class HeroAdmin(admin.ModelAdmin):
...
search_fields = ['hname']123
增加与修改页选项
fields:显示字段的顺序,如果使用元组表示显示到一行上
class HeroAdmin(admin.ModelAdmin):
...
fields = [('hname', 'hcontent')]123
fieldsets:分组显示
class HeroAdmin(admin.ModelAdmin):
...
fieldsets = (
('base', {'fields': ('hname')}),
('other', {'fields': ('hcontent')})
)123456
fields与fieldsets两者选一
InlineModelAdmin对象
类型InlineModelAdmin:表示在模型的添加或修改页面嵌入关联模型的添加或修改
子类TabularInline:以表格的形式嵌入
子类StackedInline:以块的形式嵌入
class HeroInline(admin.TabularInline):
model = HeroInfo
class BookAdmin(admin.ModelAdmin):
inlines = [
HeroInline,
]1234567
重写admin模板
在项目所在目录中创建templates目录,再创建一个admin目录
设置模板查找目录:修改settings.py的TEMPLATES项,加载模板时会在DIRS列表指定的目录中搜索
'DIRS': [os.path.join(BASE_DIR, 'templates')],1
从Django安装的目录下(django/contrib/admin/templates)将模板页面的源文件admin/base_site.html拷贝到第一步建好的目录里
编辑base_site.html文件
刷新页面,发现以刚才编辑的页面效果显示
其它管理后台的模板可以按照相同的方式进行修改
分页
Django提供了一些类实现管理数据分页,这些类位于django/core/paginator.py中
Paginator对象
Paginator(列表,int):返回分页对象,参数为列表数据,每面数据的条数
属性
count:对象总数
num_pages:页面总数
page_range:页码列表,从1开始,例如[1, 2, 3, 4]
方法
page(num):下标以1开始,如果提供的页码不存在,抛出InvalidPage异常
异常exception
InvalidPage:当向page()传入一个无效的页码时抛出
PageNotAnInteger:当向page()传入一个不是整数的值时抛出
EmptyPage:当向page()提供一个有效值,但是那个页面上没有任何对象时抛出
Page对象
创建对象
Paginator对象的page()方法返回Page对象,不需要手动构造
属性
object_list:当前页上所有对象的列表
number:当前页的序号,从1开始
paginator:当前page对象相关的Paginator对象
方法
has_next():如果有下一页返回True
has_previous():如果有上一页返回True
has_other_pages():如果有上一页或下一页返回True
next_page_number():返回下一页的页码,如果下一页不存在,抛出InvalidPage异常
previous_page_number():返回上一页的页码,如果上一页不存在,抛出InvalidPage异常
len():返回当前页面对象的个数
迭代页面对象:访问当前页面中的每个对象
示例
创建视图pagTest
from django.core.paginator import Paginator
def pagTest(request, pIndex):
list1 = AreaInfo.objects.filter(aParent__isnull=True)
p = Paginator(list1, 10)
if pIndex == '':
pIndex = '1'
pIndex = int(pIndex)
list2 = p.page(pIndex)
plist = p.page_range
return render(request, 'booktest/pagTest.html', {'list': list2, 'plist': plist, 'pIndex': pIndex})1234567891011
配置url
url(r'^pag(?P[0-9]*)/$', views.pagTest, name='pagTest'),1
定义模板pagTest.html
{%for area in list%}
{%endfor%}
{%for pindex in plist%}
{%if pIndex == pindex%}
{{pindex}}
{%else%}
{{pindex}}
{%endif%}
{%endfor%}
123456789101112131415161718192021
使用Ajax
使用视图通过上下文向模板中传递数据,需要先加载完成模板的静态页面,再执行模型代码,生成最张的html,返回给浏览器,这个过程将页面与数据集成到了一起,扩展性差
改进方案:通过ajax的方式获取数据,通过dom操作将数据呈现到界面上
推荐使用框架的ajax相关方法,不要使用XMLHttpRequest对象,因为操作麻烦且不容易查错
jquery框架中提供了. a j a x 、 .ajax、.ajax、.get、$.post方法,用于进行异步交互
由于csrf的约束,推荐使用$.get
示例:实现省市区的选择
最终实现效果如图:
引入js文件
js文件属于静态文件,创建目录结构如图:
修改settings.py关于静态文件的设置
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]1234
在models.py中定义模型
class AreaInfo(models.Model):
aid = models.IntegerField(primary_key=True)
atitle = models.CharField(max_length=20)
aPArea = models.ForeignKey('AreaInfo', null=True)1234
生成迁移
python manage.py makemigrations
python manage.py migrate12
通过workbench向表中填充示例数据
参见“省市区.sql”
注意将表的名称完成替换
在views.py中编写视图
index用于展示页面
getArea1用于返回省级数据
getArea2用于根据省、市编号返回市、区信息,格式都为字典对象
from django.shortcuts import render
from django.http import JsonResponse
from models import AreaInfo
def index(request):
return render(request, 'ct1/index.html')
def getArea1(request):
list = AreaInfo.objects.filter(aPArea__isnull=True)
list2 = []
for a in list:
list2.append([a.aid, a.atitle])
return JsonResponse({'data': list2})
def getArea2(request, pid):
list = AreaInfo.objects.filter(aPArea_id=pid)
list2 = []
for a in list:
list2.append({'id': a.aid, 'title': a.atitle})
return JsonResponse({'data': list2})1234567891011121314151617181920
在urls.py中配置urlconf
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index),
url(r'^area1/$', views.getArea1),
url(r'^([0-9]+)/$', views.getArea2),
]12345678
主urls.py中包含此应用的url
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^', include('ct1.urls', namespace='ct1')),
url(r'^admin/', include(admin.site.urls)),
]1234567
定义模板index.html
在项目中的目录结构如图:
修改settings.py的TEMPLATES项,设置DIRS值
'DIRS': [os.path.join(BASE_DIR, 'templates')],1
定义模板文件:包含三个select标签,分别存放省市区的信息
1234567891011121314151617
在模板中引入jquery文件
[removed][removed]1
编写js代码
绑定change事件
发出异步请求
使用dom添加元素
[removed]
$(function(){
$.get('area1/',function(dic) {
pro=$('#pro')
$.each(dic.data,function(index,item){
pro.append('');
})
});
$('#pro').change(function(){
$.post($(this).val()+'/',function(dic){
city=$('#city');
city.empty().append('');
$.each(dic.data,function(index,item){
city.append('');
})
});
});
$('#city').change(function(){
$.post($(this).val()+'/',function(dic){
dis=$('#dis');
dis.empty().append('');
$.each(dic.data,function(index,item){
dis.append('');
})
})
});
});
[removed]1234567891011121314151617181920212223242526272829303132
富文本编辑器
借助富文本编辑器,管理员能够编辑出来一个包含html的页面,从而页面的显示效果,可以由管理员定义,而不用完全依赖于前期开发人员
此处以tinymce为例,其它富文本编辑器的使用可以自行学习
使用编辑器的显示效果为:
下载安装
在网站pypi网站搜索并下载"django-tinymce-2.4.0"
解压
tar zxvf django-tinymce-2.4.0.tar.gz1
进入解压后的目录,工作在虚拟环境,安装
python setup.py install1
应用到项目中
在settings.py中为INSTALLED_APPS添加编辑器应用
INSTALLED_APPS = (
...
'tinymce',
)1234
在settings.py中添加编辑配置项
TINYMCE_DEFAULT_CONFIG = {
'theme': 'advanced',
'width': 600,
'height': 400,
}12345
在根urls.py中配置
urlpatterns = [
...
url(r'^tinymce/', include('tinymce.urls')),
]1234
在应用中定义模型的属性
from django.db import models
from tinymce.models import HTMLField
class HeroInfo(models.Model):
...
hcontent = HTMLField()123456
在后台管理界面中,就会显示为富文本编辑器,而不是多行文本框
自定义使用
定义视图editor,用于显示编辑器并完成提交
def editor(request):
return render(request, 'other/editor.html')12
配置url
urlpatterns = [
...
url(r'^editor/$', views.editor, name='editor'),
]1234
创建模板editor.html
[removed][removed]
[removed]
tinyMCE.init({
'mode':'textareas',
'theme':'advanced',
'width':400,
'height':100
});
[removed]
123456789101112131415161718192021222324
定义视图content,接收请求,并更新heroinfo对象
def content(request):
hname = request.POST['hname']
hcontent = request.POST['hcontent']
heroinfo = HeroInfo.objects.get(pk=1)
heroinfo.hname = hname
heroinfo.hcontent = hcontent
heroinfo.save()
return render(request, 'other/content.html', {'hero': heroinfo})12345678910
添加url项
urlpatterns = [
...
url(r'^content/$', views.content, name='content'),
]1234
定义模板content.html
姓名:{{hero.hname}}
{%autoescape off%}
{{hero.hcontent}}
{%endautoescape%}
12345678910111213
缓存
对于中等流量的网站来说,尽可能地减少开销是必要的。缓存数据就是为了保存那些需要很多计算资源的结果,这样的话就不必在下次重复消耗计算资源
Django自带了一个健壮的缓存系统来保存动态页面,避免对于每次请求都重新计算
Django提供了不同级别的缓存粒度:可以缓存特定视图的输出、可以仅仅缓存那些很难生产出来的部分、或者可以缓存整个网站
设置缓存
通过设置决定把数据缓存在哪里,是数据库中、文件系统还是在内存中
通过setting文件的CACHES配置来实现
参数TIMEOUT:缓存的默认过期时间,以秒为单位,这个参数默认是300秒,即5分钟;设置TIMEOUT为None表示永远不会过期,值设置成0造成缓存立即失效
CACHES={
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'TIMEOUT': 60,
}
}123456
可以将cache存到redis中,默认采用1数据库,需要安装包并配置如下:
安装包:pip install django-redis-cache
CACHES = {
"default": {
"BACKEND": "redis_cache.cache.RedisCache",
"LOCATION": "localhost:6379",
'TIMEOUT': 60,
},
}123456789
可以连接redis查看存的数据
连接:redis-cli
切换数据库:select 1
查看键:keys *
查看值:get 键1234
单个view缓存
django.views.decorators.cache定义了cache_page装饰器,用于对视图的输出进行缓存
示例代码如下:
from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def index(request):
return HttpResponse('hello1')
#return HttpResponse('hello2')123456
cache_page接受一个参数:timeout,秒为单位,上例中缓存了15分钟
视图缓存与URL无关,如果多个URL指向同一视图,每个URL将会分别缓存
模板片断缓存
使用cache模板标签来缓存模板的一个片段
需要两个参数:
缓存时间,以秒为单位
给缓存片段起的名称
示例代码如下:
{% load cache %}
{?che 500 hello %}
hello1
{% endcache %}12345
底层的缓存API
from django.core.cache import cache
设置:cache.set(键,值,有效时间)
获取:cache.get(键)
删除:cache.delete(键)
清空:cache.clear()123456
全文检索
全文检索不同于特定字段的模糊查询,使用全文检索的效率更高,并且能够对于中文进行分词处理
haystack:django的一个包,可以方便地对model里面的内容进行索引、搜索,设计为支持whoosh,solr,Xapian,Elasticsearc四种全文检索引擎后端,属于一种全文检索的框架
whoosh:纯Python编写的全文搜索引擎,虽然性能比不上sphinx、xapian、Elasticsearc等,但是无二进制包,程序不会莫名其妙的崩溃,对于小型的站点,whoosh已经足够使用
jieba:一款免费的中文分词包,如果觉得不好用可以使用一些收费产品
操作
1.在虚拟环境中依次安装包
pip install django-haystack
pip install whoosh
pip install jieba123
2.修改settings.py文件
添加应用
INSTALLED_APPS = (
...
'haystack',
)1234
添加搜索引擎
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',
'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
}
}
#自动生成索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'123456789
3.在项目的urls.py中添加url
urlpatterns = [
...
url(r'^search/', include('haystack.urls')),
]1234
4.在应用目录下建立search_indexes.py文件
# coding=utf-8
from haystack import indexes
from models import GoodsInfo
class GoodsInfoIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
def get_model(self):
return GoodsInfo
def index_queryset(self, using=None):
return self.get_model().objects.all()12345678910111213
5.在目录“templates/search/indexes/应用名称/”下创建“模型类名称_text.txt”文件
#goodsinfo_text.txt,这里列出了要对哪些列的内容进行检索
{{ object.gName }}
{{ object.gSubName }}
{{ object.gDes }}1234
6.在目录“templates/search/”下建立search.html
{% if query %}
搜索结果如下:
{% for result in page.object_list %}
{{ result.object.gName }}
{% empty %}
啥也没找到
{% endfor %}
{% if page.has_previous or page.has_next %}
{% if page.has_previous %}{% endif %}« 上一页{% if page.has_previous %}{% endif %}
|
{% if page.has_next %}{% endif %}下一页 »{% if page.has_next %}{% endif %}
{% endif %}
{% endif %}
123456789101112131415161718192021222324
7.建立ChineseAnalyzer.py文件
保存在haystack的安装文件夹下,路径如“/home/python/.virtualenvs/django_py2/lib/python2.7/site-packages/haystack/backends”
import jieba
from whoosh.analysis import Tokenizer, Token
class ChineseTokenizer(Tokenizer):
def __call__(self, value, positions=False, chars=False,
keeporiginal=False, removestops=True,
start_pos=0, start_char=0, mode='', **kwargs):
t = Token(positions, chars, removestops=removestops, mode=mode,
**kwargs)
seglist = jieba.cut(value, cut_all=True)
for w in seglist:
t.original = t.text = w
t.boost = 1.0
if positions:
t.pos = start_pos + value.find(w)
if chars:
t.startchar = start_char + value.find(w)
t.endchar = start_char + value.find(w) + len(w)
yield t
def ChineseAnalyzer():
return ChineseTokenizer()123456789101112131415161718192021222324
8.复制whoosh_backend.py文件,改名为whoosh_cn_backend.py
注意:复制出来的文件名,末尾会有一个空格,记得要删除这个空格
from .ChineseAnalyzer import ChineseAnalyzer
查找
analyzer=StemmingAnalyzer()
改为
analyzer=ChineseAnalyzer()12345
9.生成索引
初始化索引数据
python manage.py rebuild_index1
10.在模板中创建搜索栏
1234
celery
官方网站
中文文档
示例一:用户发起request,并等待response返回。在本些views中,可能需要执行一段耗时的程序,那么用户就会等待很长时间,造成不好的用户体验
示例二:网站每小时需要同步一次天气预报信息,但是http是请求触发的,难道要一小时请求一次吗?
使用celery后,情况就不一样了
示例一的解决:将耗时的程序放到celery中执行
示例二的解决:使用celery定时执行
名词
任务task:就是一个Python函数
队列queue:将需要执行的任务加入到队列中
工人worker:在一个新进程中,负责执行队列中的任务
代理人broker:负责调度,在布置环境中使用redis
使用
安装包
celery==3.1.25
celery-with-redis==3.0
django-celery==3.1.17123
配置settings
INSTALLED_APPS = (
...
'djcelery',
}
...
import djcelery
djcelery.setup_loader()
BROKER_URL = 'redis://127.0.0.1:6379/0'
CELERY_IMPORTS = ('应用名称.task')1234567891011
在应用目录下创建task.py文件
import time
from celery import task
@task
def sayhello():
print('hello ...')
time.sleep(2)
print('world ...')12345678
迁移,生成celery需要的数据表
python manage.py migrate1
启动Redis
sudo redis-server /etc/redis/redis.conf1
启动worker
python manage.py celery worker --loglevel=info1
调用语法
function.delay(parameters)1
使用代码
#from task import *
def sayhello(request):
print('hello ...')
import time
time.sleep(10)
print('world ...')
# sayhello.delay()
return HttpResponse("hello world")
双击打开pycharm开发工具,点击File菜单,选择Settings,安装django
再次点击File--->New Project,选择Django,配置编译器
创建完毕框架项目,可以查看到项目结构,以及配置文件
打开amn文件夹下的setting.py,查看INSTALLED_APPS配置
点击右上角的Edit Configuration,配置运行相关的属性
检查发现,新建的django项目,重新打开窗口,需要重新安装django
只要你使用ORM创建了对象,如果没有在数据中创建对应的表,执行这个命令行就会在数据库中生成对应的表。
相关问题推荐
Django是一个开放源代码的Web应用框架,由Python写成。采用了MVT的框架模式,即模型M,视图V和模板T。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是CMS(内容管理系统)软件。并于2005年7月在BSD许可证下发布。这套框架是以比...
使用类似pymysql的第三方模块,在Python代码中嵌入SQL语句,可以直接访问数据库。对于轻量级的SQLite,Django和Python原生支持,连第三方模块都不需要就可以访问。
FlaskFlask确实很轻,不愧是Micro Framework,从Django转向Flask的开发者一定会如此感慨,除非二者均为深入使用过Flask自由、灵活,可扩展性强,第三方库的选择面广,开发时可以结合自己最喜欢用的轮子,也能结合最流行最强大的Python库入门简单,即便没有多...
打开 Linux 或 MacOS 的 Terminal (终端)直接在 终端中输入windows 快捷键 win + R,输入 cmd,直接在 cmd 上输入1、新建一个项目django-admin.py startproject 项目名1以下命令要先进入项目目录下才能执行:cd 项目名2、新建app (一个项目可以有多个app...
Django的默认数据库是sqlite3
Django中避免sql注入的方法:1、对用户的输入进行校验;2、不要使用动态拼装sql;3、不要把机密信息直接存放;4、应用的异常信息应该给出尽可能少的提示;5、利用Dajngo的ORM来有效避免sql注入。什么是SQL注入?所谓SQL注入,就是通过把SQL命令插入到Web表单...
中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能...
项目主要页面介绍1.首页2.注册3.登录2.项目开发模式开发模式前后端不分离后端框架Django+Jinja2模板引擎前端框架Vue.js3.准备项目代码仓库源码托管网站1、码云(https://gitee.com/)2、创建源码远程仓库:website3、克隆项目代码仓库新建文件夹下载githttps:...
from django.http import FileResponsefrom django.utils.encoding import escape_uri_path def build_download_response(filepath, filename): 构建下载文件的文件头 :param filepath: 文件路径 :param filenam...
Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出。中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性。我们可以使用中间件,在Django处理视图的不同阶段对输入或输出...
django现在在生产环境用得还是比较多的,但是只能说数量比较多,质量很差;意思就是,越大型的项目越不会选django,因为它封装得太好,不够灵活,一般快速上马项目可以,但是长期维护下来很难受一般如果有开发团队的都选flask和tornado...
什么是 middleware什么时候使用 middleware我们写 middleware 必须要记住的东西写一些 middlewares 来理解中间件的工作过程和要点什么是 middlewareMiddlewares 是修改 Django request 或者 response 对象的钩子. 下面是Django 文档中的一段描述。Middlew...
客户端与服务端交互(知识点)浏览器就是客户端服务端开放端口和连接即可客户端服务器代码实现# -*- coding: utf-8 -*-__author__ = 'HeYang'__time__ = '2018/6/7 2:57'import socket sock = socket.socket()sock.bind(('1...
Django中间件有很多,入session、csrf、contexttype等,能力强的朋友还可以自己写中间件。
django中间件主要有两个作用1·中间件是介于request 和 response 处理之间的一道处理过程,用于全局范围改变Django的输入和输出,简单的来说中间件是帮助我们在视图函数指向之前和执行之后都可以做一些额外的操作2·Django项目中默认启用了csrf保护,每次请求...
中间件 Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出。中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性。中间件Django中的中间件是一个轻量级、底层的插件系统...