静态文件配置
-
在setting.py中最底下有一个叫做static的文件夹,主要用来加载一些模板中用到的资源,提供给全局使用
-
这个静态文件主要用来配置CSS,HTML,图片,字体文件等
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static')
]
- 之后在模板中,首先加载静态文件,之后调用静态,就不用写绝对全路径了
图片上传
- 文件存储在request.FILES属性中
- form表单上传文件需要添加enctype=‘multipart/from-data’
- 文件上传必须使用POST请求方式
存储
- 在static文件夹下创建uploadefiles用于存储接受上传的文件
- 在settings中配置,MEDIA_ROOT=os.path.join(BASE_DIR, r’static/uploadefiles)
- 在开发中通常是存储的时候,我们要存储到关联用户的表中
def upload_file(request):
if request.method == "POST":
icon = request.FILES.get("icon")
with open("/----/static/img/icon.jpg", "wb") as save_file:
for part in icon.chuncks():
save_file.write(part)
save_file.flush()
return HttpResponse("文件上传成功")
- Django自带
# models
class UserModel(models.Model):
u_name = models.CharField(max_length=16)
# upload_to 相对路径, 相对于的是MEDIA_ROOT 媒体根目录
u_icon = models.ImageField(upload_to='%Y/%m/%d/icons')
# Settings
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/upload')
# Terminal
pip install pillow -i
# 存储图片
def image_field(request):
if request.method == "POST":
username = request.POST.get("username")
icon = request.POST.get("icon")
user = User()
user.u_name = username
user.i_icon = icon
user.save()
return HttpResponse(---)
# 读取图片
def mine(request):
username = request.GET.get("username")
user = User.objects.get(u_name=username)
data = {
"username": username,
"url": "/static/upload" + user.u_icon.url
}
return ----
缓存
- 缓存框架的核心目的
- 较少的代码
- 一致性
- 可扩展性
- 提升服务器响应速度
- 将执行过的操作数据存储下来,在一定时间内,再次获取数据的时候,直接从缓存中获取
- 比较理想的方案,缓存使用内存级缓存
- Django内置缓存框架
- 基于Memcached缓存
- 使用数据库进行缓存
- 使用文件系统进行缓存
- 使用本地内存进行缓存
- 提供缓存扩展接口
缓存配置
-
创建缓存表
python manage.y createcachetable [table_name]
- 缓存配置
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', 'LOCATION': 'my_cache_table', 'TIMEOUT': 60*5, # 以下部分可以不填 'OPTIONS': { 'MAX_ENTRIES': '300', }, # 前置字符串 'KEY_PREFIX': 'rock', 'VERSION': '1', } }
-
缓存的使用
- 在视图中使用(使用最多的场景)
- @cache_page()
- time 秒,缓存时间
- cache 缓存配置,默认default
- key_prefix 前置字符串
-
缓存底层
-
获取cache(多个)
-
from django.core.cache import caches cache = caches['cache_name']
-
获取cache(单个)
-
from django.core.cache import cache
-
-
缓存操作
- cache.set
- key
- value
- timeout
- get
- add
- get_or_set
- get_many
- set_many
- delete
- delete_many
- clear
- incr 增加
- incr(key, value) key对应的值上添加value
- decr 减少
- decr(key, value) key对应的值上减少value
- 如果value不写,默认变更为1
- cache.set
使用Redis做缓存
-
常见的有两个实现
-
pip install django-redis
- http://django-redis-chs.readthedocs.io/zh_CN/latest/#djangodjango-redis-cache
-
pip install django-redis-cache
-
https://pypi.python.org/pypi/django-redis-cache/
-
配置和内置的缓存配置基本一致
-
CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': 'redis://127.0.0.1:6379/1', 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.DefaultClient', }, } }
-
aop 面向切面
-
中间件:是一个轻量级的,底层的插件,可以介入Django的请求和响应过程(面向切面编程)
-
中间件的本质就是一个python类
-
实现统计功能
- 统计ip
- 统计浏览器
-
实现权重控制
class HelloMiddle(MiddlewareMixin): def process_request(self, request): print(request.META.get('REMOTE_ADDR')) ip = request.META.get('REMOTE_ADDR') if ip == '127.0.0.1': return HttpResponse("恭喜发财大傻逼") else: return HttpResponse('hhh')
- 黑名单
- 白名单
-
实现反爬
-
反爬虫
class HelloMiddle(MiddlewareMixin): def process_request(self, request): ip = request.META.get('REMOTE_ADDR') if request.path == "/app/getticket/": result = cache.get(ip) if result: return HttpResponse('您的访问过于频繁') cache.set(ip, ip, timeout=10)
class HelloMiddle(MiddlewareMixin): def process_request(self, request): ip = request.META.get('REMOTE_ADDR') requests = cache.get(ip, []) black_list = cache.get(ip, []) if ip in black_list: return HttpResponse('您已被拉黑无法操作') while requests and time.time() - requests[-1] > 60: requests.pop() request.insert(0, time.time(), timeout=60) cache.set(ip, requests, timeout=60) if len(requests) >=30: black_list.append(ip) cache.set('black', black_list, timeout=60*60*24) return HttpResponse('您已被拉黑') if len(requests) >= 10: return HttpResponse('请求次数过于频繁')
- 十秒之内只能搜索一次
-
-
界面友好化
-
应用交互友好化
中间件
- 调用顺序
- 中间件注册的时候是一个列表
- 如果我们没有在切点处进行返回,中间件会依次执行
- 如果我们直接进行了返回,后续中间件就不再执行了
- 切点
- process_request
- process_view
- process_template_response
- process_response
- process_exception
切入函数
- __ init __ :没有参数,服务器响应第一个请求的时候自动调用,用户确定是否启用该中间件
- process_request(self, request):在执行视图之前被调用,每个请求上都会调用,不主动进行返回或返回HttpResponse对象
- process_template_repsonse(self, request, response):在视图刚好执行完后进行调用,每个请求都会调用,不主动进行返回或返回HttpResponse对象
- process_response(self, request, response):所有响应返回浏览器之前调用,每个请求都会调用,不主动进行返回或返回HttpResponse对象
- process_exception(self, request, exception):当视图抛出异常时调用,不主动进行返回或返回HttpResponse对象
def process_exception(self, request, exception):
print(request)
print(exception)
return HttpResponse('错误')
-
自定义中间件流程
-
在工程目录下创建middleware目录
-
目录中创建一个python文件
-
在python文件中导入中间件的基类
-
from django.utils.deprecation import MiddlewareMixin
-
-
在类中根据功能需求,创建切入需求类,重写切入点方法
-
class LearAOP(MiddlewareMixin): def process_request(self.request): print('request的路径', request.GET.path)
-
-
启用中间件,在setting中进行配置,MIDDLEWARE中添加middleware.文件名.类名
-
分页
-
django提供了分页的工具,存在于django.core中
- Paginator 数据分页工具
- Page 具体的某一分页
-
Paginator:
- 对象创建 Paginator(数据集,每一页数据数)
- 属性:
- count 对象总数
- num_pages 页面总数
- page_range 页码列表,从1开始
-
方法 page(整数) 获得一个page对象
- object_list 当前页面上所有的数据对象
- number 当前页的页码值
- paginator 当前page关联的Paginator对象
- 常见错误
- InvalidPage: page()传递无效页码
- PageNotAnInteger: page()传递的不是整数
- Empty: page()传递的值有效,但是没有数据
- 自定义
def get_students(request): page = request.GET.get('page', 1) per_page = request.GET.get('per_page', 10) students = Student.objects.all()[per_page*(page-1): page*per_page] data = { 'students': students } return render(request----)
- django内置
def get_students(request): page = request.GET.get('page', 1) per_page = request.GET.get('per_page', 10) students = Student.objects.all() paginator = Paginator(students, per_page) page_object = paginator.page(page) data = { "page_object": page_object, "page_range": paginator.page_range, } return render(request----)
验证码
- 验证码需要使用绘图pillow
- 核心 Image, ImageDraw, ImageFont
def login(request):
receive_code = request.POST.get('verify_code')
store_code = request.session.get('verify_code')
if receive_code.lower() != store_code.lower():
return ---
else:
return ---
def get_code(request):
# 初始化画布,初始化画笔
mode = "RGB"
size = (200, 100)
red = get_color()
green = get_color()
blue = get_color()
color_bg = (red, green, blue)
image = Image.new(mode=mode, size=size, color=color_bg)
imagedraw = ImageDraw(image, mode=mode)
imagefont = ImageFont.truetype(settings.FONT_PATH, 100)
verify_code = generate_code()
request.session['verify_code'] = verify_code
for i in range(4):
fill = (get_color(), get_color(), get_color())
imagedraw.text(xy=(50*i, 0), text=verify_code[i], font=imagefont, fill=fill)
for i in range(5000):
fill = (get_color(), get_color(), get_color())
xy = (random.randrange(201), random.randrange(100))
imagedraw.point(xy=(), fill=fill)
fp = BytesIO()
image.save(fp, "png")
return HttpResponse(fp.getvalue(), content_type="image/png")
def get_color():
return random.randrange(256)
def generate_code():
source = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890"
for i in range(4):
code += random.choice(source)
return code
富文本
-
django的插件
- pip install django-tinymce
-
用处:
- 在后台管理中使用
- 在页面中使用,通常用来做博客
-
后台中使用
-
配置settings.py文件
- INSTALLED_APPS添加tinymce应用
-
添加默认配置
TINYMCE_DEFAULT_COUNFIG = { 'theme': 'advanced', 'width': 800, 'height': 600, }
-
创建模型类:
from tinymce.models import HTMLField class Blog(models.Model): sBlog = HTMLField()
-
配置站点
admin.site.register
-