接外包,有相关需求的可以联系我:Telegram | Email

Django 高级教程

该文章创建(更新)于06/7/2022,请注意文章的时效性!

静态文件

  • css、js、图片、JSON文件、字体文件等等

  • 配置settings.py

STATIC_URL = '/static/'  
STATICFILES_DIRS = [  
    os.path.join(BASE_DIR, 'static'),  
]
  • HTML
<link rel="stylesheet" type="text/css" href="{% static '/myApp/css/style.css' %}">

中间件

一个轻量级、底层的插件,可以介入Django的请求和响应。本质是一个Python类

方法

  • __init__
    • 不需要传参,服务器响应第一个请求的时候自动调用,用于确定是否启用改中间件。
  • process_request(self,request)
    • 在执行视图之前被调用(分配url匹配视图之前),每个请求上都会调用,返回None或HttpResponse对象
  • process_view(self,request,view_function,view_args,view_kwargs)
    • 调用视图之前执行,每个请求都会调用,返回None或HttpResponse对象
  • process_template_response(request,response)
    • 在视图刚好执行完后调用,每个请求都会调用,返回None或HttpResponse对象
    • 可以使用render
  • process_response(self,request,response)
    • 所有响应返回浏览器之前调用,每个请求都会调用,返回HttpResponse对象
  • process_exception(self,request,exception)
    • 当视图抛出异常调用时,返回HttpResponse对象

自定义中间件

  • 在工程目录下创建文件夹middleware及文件myMiddle.py
from  django.utils.deprecation import MiddlewareMixin  


class MyMiddle(MiddlewareMixin):  
    def process_request(self,request):  
        print("get参数为:",request.GET.get('a'))
  • 使用自定义中间件,在settings.py中配置即可
'middleware.myApp.myMiddle.MyMiddle', # 自定义中间件

上传图片

文件上传时,文件数据存储在request.FILES属性中

  • 注意上传文件form表单要加enctype="multipart/form-data"
<form method="post" action="/savefile/" enctype="multipart/form-data">  
    {% csrf_token %}  
  <input type="file" name="file">  
  <input type="submit" value="upload">  
</form>
  • 上传文件必须是post请求

存储路径

  • 在static目录下创建目录用于储存接收上传的文件
  • settings.py中配置,注意路径在linux和windows中的差别
# 上传文件路径  
MEDIA_ROOT=os.path.join(BASE_DIR,r'static\uploadfile')

存储代码

import os  
from django.conf import settings
def savefile(request):  
    if request.method == "POST":  
        f = request.FILES.get("file")  
        # 文件在服务器的路径  
        filePath = os.path.join(settings.MEDIA_ROOT, f.name)  
        # 打开特定的文件进行二进制的写操作  
        with open(filePath, 'wb+') as destination:  
            # 分块写入文件  
            for chunk in f.chunks():  
                destination.write(chunk)  
        return HttpResponse("上传成功")  
    else:  
        return HttpResponse("上传失败")

分页

Paginator对象

  • 创建对象,并返回分页对象
Paginator(列表,整数)
  • 属性
    • count 对象总数
    • num_pages 分页总数
    • page_range 页码列表,列如:[1,2,3,4,5]页码从1开始
  • 方法

page(num) 获取一个Page对象,如果提供的页码不存在,会抛出异常InvalidPage

  • 异常
    • InvalidPage 当向page()传递的是一个无效的页码时抛出
    • PageNotAnInteger 当向Page()传递的不是一个整数时抛出
    • EmptyPage 当向Page()传递一个有效值,但是该页面没有数据抛出时

Page对象

  • 创建对象

Paginator对象的page()方法会得到Page对象,不需要手动创建

  • 属性
    • object_list 当前页上所有的数据(对象)列表
    • number 当前页的页码值
    • paginator 当前page对象关联的paginator对象
  • 方法
    • has_next() 判断是否有下一页,如果有返回True
    • has_previous() 判断是否有上一页,如果有返回True
    • has_other_pages() 判断是否有上一页或下一页,如果有返回True
    • has_page_number() 返回下一页的页码,如果下一页不存在抛出InvalidPage异常
    • previous_page_number() 返回上一页的页码,如果有上一页不存在抛出InvalidPage异常。
    • len() 返回当前页的数据(对象)的个数

test case

  • 路由
url(r'^studentpage/(\d+)/$',views.studentpage,name='studentpage'),
  • view
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger  
def studentpage(request,pageid):  
    # 所有学生列表  
    allList = Students.stuObj.all()  
    # 分页,每页6条  
    paginator = Paginator(allList, 6)  
    # 获取当前页码  
    page = paginator.page(pageid)  
    return render(request, 'myApp/studentpage.html',{"students": page})
  • html
<h1>学生分页显示</h1>  
<ul>  
    {% for student in students %}  
        <li>{{ student.sname }}</li>  
    {% endfor %}  
</ul>  

<ul>  
    {% for index in students.paginator.page_range %}  
        <li><a href="/studentpage/{{ index }}">{{ index }}</a></li>  
    {% endfor %}  
</ul>

AJAX

  • 网页需要动态生成,请求JSON数据
  • 模板配置
{% load static %}  

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>Title</title>  
    <script type="text/javascript" src="{% static '/myApp/js/jquery-3.3.1.min.js' %}"></script>  
    <script type="text/javascript" src="{% static '/myApp/js/emperinter.js' %}"></script>  
</head>  
<body>  
    <h1>StudentsInfo</h1>  

    <button id="btn">Get Students</button>  

</body>  
</html>
  • js配置
$(document).ready(function(){  
    document.getElementById("btn").onclick=function(){  
        $.ajax({  
            url:"/studentsinfo/",  
            type:"get",  
            dataType:"json",  
            success:function(data,status){  
                console.log(data);  
                var d = data["data"];  
                for(var i = 0;i < d.length;i++){  
                    document.write("<p>姓名:"+d[i][0]+"</p>");  
                }  
            }  
        })  
    }  
});
  • 路由配置
url(r'^ajaxstudent/$',views.ajaxstudent,name='ajaxstudent'),  
url(r'^studentsinfo/$',views.studentsinfo,name='studentsinfo'),
  • 视图配置
from django.http import JsonResponse  
def studentsinfo(request):  
    # 所有学生列表  
    all = Students.stuObj.all()  
    allList = []  
    for stu in all:  
        allList.append([stu.sname,stu.sage])  
    return JsonResponse({"data":allList})

富文本

  • 安装package
pip install django-tinymce -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com 

在站点中使用

  • 配置settings.py中配置
INSTALLED_APPS = [  
    'django.contrib.admin',  
    'django.contrib.auth',  
    'django.contrib.contenttypes',  
    'django.contrib.sessions', # session配置  
    'django.contrib.messages',  
    'django.contrib.staticfiles',  
    'myApp', # 激活应用  
    'tinymce', # 富文本编辑器  
]

富文本配置文件

TINYMCE_DEFAULT_CONFIG = {  
    'theme': 'advanced',  
    'height': 360,  
    'width': 1120,  
}
  • 创建模型类
from tinymce.models import HTMLField
class Text(models.Model):
    str = HTMLField()
  • 注册模型
from .models import Grades, Students,Text  
admin.site.register(Text)

在自定义视图中使用

怎么感觉就是写个网页?

  • 模板配置
<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>富文本</title>  
    <script type="text/javascript" src="/static/tiny_mce/tinymce.min.js"></script>  
    <script type="text/javascript">  
        tinyMCE.init({  
            'mode':'textareas',  
            'theme':"advanced",  
            'widht':'600',  
            'height':'300',  
        })  
    </script>  
</head>  
<body>  
    <h1>Edit</h1>  
    <form method="post">  
        <textarea name="str">emperinter</textarea>  
        <input type="submit" value="Edit">  
    </form>  
</body>  
</html>


👇 Share | 分享 👇


要不赞赏一下?

微信
支付宝
PayPal
Bitcoin

版权声明 | Copyright

除非特别说明,本博客所有作品均采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。转载请注明转自-
https://www.emperinter.info/2022/06/07/django-advanced-tutorial/


要不聊聊?

我相信你准备留下的内容是经过思考的!【勾选防爬虫,未勾选无法留言】

*

*



微信公众号

👉 NewsLetter ❤️ 邮箱订阅 👈

优惠码


阿里云国际版20美元
Vultr10美元
搬瓦工 | Bandwagon应该有折扣吧?
域名 | namesiloemperinter(1美元)