• django修身大法之九阴真经


    ⼀、图形验证码

    1 安装django-simple-captcha库

    在网站开发的登录页面中,经常会需要使用到图形验证码来验证。在 Django中,django-simple-captcha库包提供了图形验证码的使用。

    $ pip install django-simple-captcha
    # 如果安装有依赖库问题,请执⾏下⾯的安装
    apt-get -y install libz-dev libjpeg-dev libfreetype6-dev python-dev
    

    2 设置

    ​ 图1 安装应用

    ​ 图2. 设置验证码样式

    ​ 图3. 设置路由

    最后要迁移数据库:

    python manage.py migrate
    

    3 建立表单

    # forms.py
    from django import forms
    from captcha.fields import CaptchaField
    class LoginForm(forms.Form):
         username = forms.CharField(max_length=20,min_length=3)
         password =
        forms.CharField(max_length=128,widget=forms.PasswordInput())
         captcha = CaptchaField() # 验证码字段
    

    4 实现

    # 应⽤的urls.py
    urlpatterns = [
    .....
     path('yzm/',views.user_login,name='yzm'),
    ]
    # 前端⻚⾯
    <html lang="en">
    <head>
     <meta charset="UTF-8">
     <title>登录</title>
    </head>
    <body>
    <div>{{ msg }}</div>
    <form action="{% url 'App03:yzm' %}" method="post">
     {% csrf_token %}
     
    ⽤户:{{ form.username }} <span>{{ form.username.errors.0 }}
    </span> <br>
     
    密码:{{ form.password }} <span>{{ form.password.errors.0 }}
    </span><br>
     
    验证码:{{ form.captcha }} <span>{{ form.captcha.errors.0 }}
    </span><br>
     <input type="submit">
    </form>
    </body>
    </html>
    <script src="https://cdn.bootcss.com/jquery/1.12.3/jquery.min.js">
    </script>
    <script>
     //点击刷新验证码
        $(function () {
     $('.captcha').css({
     'cursor': 'pointer'
     });
     // ajax刷新
     $('.captcha').click(function () {
     console.log('click');
     $.get("/app3/refresh/",
     function (result) {
     $('.captcha').attr('src', result['image_url']);
     $('#id_captcha_0').val(result['key'])
     });
     });
     })
    </script>
    
    
    # views.py
    import json
    from captcha.helpers import captcha_image_url
    from captcha.models import CaptchaStore
    from django.contrib.auth import authenticate
    import django.contrib.auth as auth
    from django.contrib.auth.decorators import login_required
    from django.http import HttpResponse, JsonResponse
    from django.shortcuts import render, redirect
    def user_login(request):
     if request.method == "POST":
     	form = LoginForm(request.POST)
     	if form.is_valid():
         username = form.cleaned_data.get('username')
         password = form.cleaned_data.get('password')
         user =
        authenticate(request,username=username,password=password)
         if user:
             auth.login(request,user)
             return redirect(reverse("App03:home"))
    else:
    	form = LoginForm()
         # 跳转登录⻚⾯
         return render(request,'App03/login.html',context={'form':form})
    

    ⼆、发送邮件

    1.setting配置

    # smtp服务的邮箱服务器
    EMAIL_HOST = 'smtp.163.com'
    # smtp服务固定的端⼝是25
    EMAIL_PORT = 25
    #发送邮件的邮箱
    EMAIL_HOST_USER = 'landmark_cheng@163.com'
    #在邮箱中设置的客户端授权密码
    EMAIL_HOST_PASSWORD = 'q123456'
    #收件⼈看到的发件⼈ <此处要和发送邮件的邮箱相同>
    EMAIL_FROM = 'python<landmark_cheng@163.com>'
    

    2.发送邮件

    #⼀封邮件
    from django.core.mail import send_mail
    from django.conf import settings
    def sendone(request):
         send_mail('标题', '内容', settings.EMAIL_FROM,
         ['313728420@qq.com'])
         return HttpResponse("发⼀封邮件")
     
    # 发多封邮件
    def sendmany(request):
         message1 = ('Subject here', '<b>Here is the message</b>',
        settings.EMAIL_FROM, ['313728420@qq.com'])
         message2 = ('Subject here', '<b>Here is the message</b>',
        settings.EMAIL_FROM, ['313728420@qq.com'])
         send_mass_mail((message1,message2), fail_silently=False)
         return HttpResponse('发送多封邮件')
    #渲染模板进⾏邮件发送
    def send_mail(request):
         subject, from_email, to = 'html', settings.EMAIL_FROM,
        '313728420@qq.com'
        html_content =
        loader.get_template('active.html').render({'username': '⼩花猫'})
         msg = EmailMultiAlternatives(subject, from_email=from_email, to=
        [to])
         msg.attach_alternative(html_content, "text/html")
         msg.send()
         return HttpResponse('发送html的⽂件内容')
    
    

    三、富文本编辑器

    一般用于写文章编辑內容自带样式

    • 安装:pip install django-tinymce
    • 配置

    (1) 配置settings文件

    在INSTALL_APPS 添加如下代码

    INSTALLED_APPS = [ 
        ...
         'App',
         'tinymce',
    ]
    

    在settings.py下添加如下代码

    #富⽂本编辑器的配置
    TINYMCE_DEFAULT_CONFIG = {
         'theme':'advanced',
         'width':600,
         'height':400
    }
    

    (2) 添加视图函数

    def index(req):
     if req.method == 'GET':
     	return render(req,'index.html')
     if req.method == 'POST':
     	# print(req.POST)
     
     
    Posts(title=req.POST.get('title'),content=req.POST.get('content')).sa
    ve()
     return HttpResponse('index')
    

    (3) 前台模板的展示

    <!DOCTYPE html>
    <html lang="en">
    <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <script src="/static/tiny_mce/tiny_mce.js"></script>
     <script>
     tinyMCE.init({
     'mode':'textareas',
     'width':800,
     'height':600,
     })
     </script>
    </head>
    <body>
    <form action="/" method="POST">
     {% csrf_token %}
     <p>标题 <input type="text" name="title" placeholder="请输⼊标题"
    maxlength="20" required></p>
     <textarea name="content" id="" cols="30" rows="10"></textarea>
     <input type="submit">
    </form>
    </body>
    </html>
    

    四、文件上传

    使用request.FILES 获取上传文件

    1.表单注意

    • 表单的enctype的值需要设置为:enctype="multipart/form-data
    • 表单提交类型为POST

    2.存储路径

    在settings.py文件下添加如下代码

    #设置上传⽂件路径
    MEDIA_ROOT = os.path.join(BASE_DIR,'static/upload')
    

    3. 文件上传对象的属性和方法

    名称 说明
    file.name 获取上传的名称
    file.size 获取上传大件的大小(字节)
    file.read() 读取全部(适用于小⽂件)
    file.chunks() 按块来返回文件 通过for循环进行迭代,可以将大⽂
    件按照块来写入到服务器
    file.multiple_chunks() 判断文件 是否大于2.5M 返回True或者False

    4.创建上传文件的表单

    • 模板
    <!DOCTYPE html>
    <html lang="en">
    <head>
     
    <meta charset="UTF-8">
     
    <title>Title</title>
    </head>
    <body>
    <form action="/doUpload/" method="post" enctype="multipart/form￾data">
     {% csrf_token %}
     
    <p>⽂件 <input type="file" name="file"></p>
        <p><input type="submit" value=
    "上传"></p>
    </form>
    </body>
    </html>
    
    • views.py
    from django.conf import settings
    import os
    #⽂件上传处理
    def doUpload(req):
        file = req.FILES.get('file')
        # print(file.name)
        # print(file.size)
        savePath = os.path.join(settings.MDEIA_ROOT,file.name)
        # print(savePath)
        with open(savePath,'wb') as f:
           # f.write(file.read())
            if file.multiple_chunks():
                for myf in file.chunks():
                    f.write(myf)
                 print('⼤于2.5')
            else:
                 print('⼩于2.5')
                f.write(file.read())
        return HttpResponse('⽂件上传')
    

    5.封装文件上传类

    可以自定义⼀个类实现文件上传,文件上传类可以:

    • 检查文件类型
    • 检查文件大小
    • 是否生成随机文件名
    import os
    from datetime import datetime
    from random import randint
    
    class FileUpload:
        def __init__(self,file,exts=['png','jpg','jpeg'],size=1024*1024,is_randomname=False):
         """
         :param file: ⽂件上传对象
         :param exts: ⽂件类型
         :param size: ⽂件⼤⼩,默认1M
         :param is_randomname: 是否是随机⽂件名,默认是否
         """
         self.file = file
         self.exts = exts
         self.size = size
         self.is_randomname = is_randomname
         #⽂件上传
    	 def upload(self,dest):
             """
             :param dest: ⽂件上传的⽬标⽬录
             :return:
             """
             #1 判断⽂件类型是否匹配
             if not self.check_type():
             return -1
             #2 判断⽂件⼤⼩是否符合要求
             if not self.check_size():
             return -2
             #3 如果是随机⽂件名,要⽣成随机⽂件名
             if self.is_randomname:
             self.file_name = self.random_filename()
             else:
             self.file_name = self.file.name
             #4 拼接⽬标⽂件路径
             path = os.path.join(dest,self.file_name)
             #5 保存⽂件
             self.write_file(path)
             return 1
       def check_type(self):
             ext = os.path.splitext(self.file.name)
             if len(ext) > 1:
                 ext = ext[1].lstrip('.')
                 if ext in self.exts:
                        return True
     		return False
         def check_size(self):
             if self.size < 0:
             return False
             #如果⽂件⼤⼩于给定⼤⼩,返回True,否则返回False
             return self.file.size <= self.size
         def random_filename(self):
             filename =
            datetime.now().strftime("%Y%m%d%H%M%S")+str(randint(1,10000))
             ext = os.path.splitext(self.file.name)
             #获取⽂件后缀
             ext = ext[1] if len(ext)>1 else ''
             filename += ext
             return filename
            
        def write_file(self,path):
             with open(path,'wb') as fp:
             	if self.file.multiple_chunks():
             		for chunk in self.file.chunks():
             			fp.write(chunk)
            	 else:
            		 fp.write(self.file.read())
    

    五、站点管理

    (1) 配置admin应用

    django.contrib.admin
    

    (2) 创建管理员用户

    python3 manage.py createsuperuser
    依次输入用户名->邮箱->密码->确认密码

    (3) 汉化

    LANGUAGE_CODE = 'zh-Hans'
    TIME_ZONE = 'Asia/Shanghai'
    

    (4) 在App/admin.py 里面注册自己的模型类

    from .models import Grade,Students
    #注册模型类 在后台展示
    admin.site.register(Grade)
    admin.site.register(Students)
    

    (5) 配置后台页面和添加数据的展示

    #配置数据的展示
    class GradeAdmin(admin.ModelAdmin):
        #设置显示哪些字段 
        list_display = ['pk','gname','gboynum','ggirlnum']
        #添加搜索字段
        search_fields = ['gname']
        # 分⻚
        list_per_page = 5
        # 过滤字段‘
        list_filter = ['gname']
    class StudentsAdmin(admin.ModelAdmin):
        list_display = ['pk','sname','ssex','sage','grade']
        search_fields = ['sname']
    	#分⻚
    	list_per_page = 5 
    	#过滤字段‘
        list_filter = ['sname']
        #更改添加 修改的字段属性的位置
        # fields = ['sage','ssex','sname','grade','info']
        fieldsets = [
         ("基本信息",{"fields":['sname','sage','ssex']}),
         ("其它信息",{'fields':['info','grade']}),
         ]
    
    	#字段顺序和字段分组不能同时使⽤
    #注册模型类 在后台展示
    admin.site.register(Grade,GradeAdmin)
    admin.site.register(Students,StudentsAdmin)
    

    (6) 关联对象

    #TabularInline 横着展示添加学⽣的布局
    #StackedInline 竖着展示添加学⽣的布局
    # class AddStudents(admin.TabularInline):
    class AddStudents(admin.StackedInline):
    class AddStudents(admin.TabularInline):
    	model = Students #关联的模型名称
    	extra = 2 #添加学⽣的个数
    #配置数据的展示
    class GradeAdmin(admin.ModelAdmin):
    	inlines = [AddStudents]
    

    (7) bool值的显示男女

    def sex(self):
    	if self.ssex:
    		return '男' 
    	else: 
    		return '⼥'
    	sex.short_description = 
    	'性别' # 给字段名称添加简介(字段的中⽂说明)
     
    	# list_display = ['pk','sname','ssex','sage','grade']
    	list_display = ['pk','sname',sex,'sage','grade']
    
  • 相关阅读:
    jquey 阻止表单提交
    Array.prototype.remove 删除数组元素
    <asp:HiddenField> 控件 实现键值对保存
    jquery实现倒计时
    作业
    第六周作业
    第四周作业
    第二次作业
    2021.3.4(四个题)
    增删改查
  • 原文地址:https://www.cnblogs.com/williamweson/p/13615103.html
Copyright © 2020-2023  润新知