WEB后端服务第23天-Django项目第3天

WEB后端服务第23天-Django项目第3天

一、form表单类

form表单类主要用于渲染前端form表单的,也可以用于site站点的form表单页面。

1.1 创建form表单类

通过在app模块下创建forms.py脚本,内容如下:

from django import forms
from .models import AppUser

class AppUserForm(forms.ModelForm):

    name = forms.CharField(min_length=8,
                           max_length=20,
                           required=True,
                           error_messages={
                               'required': '账户不能为空',
                               'max_length': '账户不能超过20个字符',
                               'min_length': '账户不能少于8个字符'
                           })
    auth_key = forms.CharField(widget=forms.PasswordInput(render_value=True),
                               label='口令',
                               min_length=6,
                               error_messages={
                                   'required': '口令不能为空',
                                   'min_length': ' 口令不少于6位'
                               })

    phone = forms.CharField(max_length=11,
                            min_length=11,
                            required=False, label='手机号')

    class Meta:
        model = AppUser  # 指定模型类
        fields = ('id', 'img1', 'name', 'auth_key', 'phone', 'email')
        error_messages = {
            'email': {
                'required': '邮箱不能为空'
            }
        }

在表单类中,可以声明表单字段, 字段的类型与Model模型的字段类型要一一匹配,除此之外,表单注重地的验证规则和渲染数据。

在Meta类中,error_messages是指定Model模型类的字段验证错误的提示信息。而在forms.xxxField()的erorr_messages是指定当前字段的不同验证规则 的错误信息,如required表示必填项, min_length表示最小值, max_length表示最大值。

1.2 使用form表单类

在admin.py脚本中,应用表单类

from .forms import AppUserForm

class AppUserAdmin(admin.ModelAdmin):
    list_display = ('name', 'phone', 'email', 'create_time', 'status')
    form = AppUserForm

admin.site.register(AppUser, AppUserAdmin)

1.3 自定义验证规则

通过forms的字段类可以做一些通常验证,但复杂的验证规则,需要重写clean_xxx()函数,在AppUserForm中增加验证口令的方法。规则是必须包含大写、小写和数字:

    def clean_auth_key(self):
        # 以上验证都通过了
        # 自定义验证规则: 必须包含大写、小写和数字等字符
        auth_key = self.cleaned_data.get('auth_key')
        if all((
                re.search(r'\d+', auth_key),
                re.search(r'[a-z]+', auth_key),
                re.search(r'[A-Z]+', auth_key)
        )):
            print('-----clean_auth_key-----')
            return auth_key

        raise ValidationError('口令必须包含大写、小写和数字等字符')

如果验证没有通过,form表单要收集错误信息,必须通过raise ValidationError(message)抛出异常。

二、自定义小部件widget

2.1 源码分析

django.forms.widgets.TextInput源码

class TextInput(Input):
    input_type = 'text'
    template_name = 'django/forms/widgets/text.html'
class Input(Widget):
    """
    Base class for all <input> widgets.
    """
    input_type = None  # Subclasses must define this.
    template_name = 'django/forms/widgets/input.html'

    def __init__(self, attrs=None):
        if attrs is not None:
            attrs = attrs.copy()
            self.input_type = attrs.pop('type', self.input_type)
        super().__init__(attrs)

    def get_context(self, name, value, attrs):
        context = super().get_context(name, value, attrs)
        context['widget']['type'] = self.input_type
        return context

init()函数是在表单字段中指定的参数

get_context()是在渲染模板时,返回的上下文数据

2.2 创建资源

​ 在app模块下创建widgets.py脚本和templates模板目录,widgets.py脚本的内容如下:

# 自动生成ID的输入框
class IDWidget(TextInput):
    def get_context(self, name, value, attrs):
        # 新增用户时
        if not value:
            value = uuid.uuid4().hex

        return super().get_context(name, value, attrs)
# 发送邮件的按钮
class SendEmailWidget(TextInput):
    template_name = 'send_email_widget.html'

    # render_value 是否渲染现有的值
    def __init__(self, attrs=None, render_value=True):
        super().__init__(attrs)
        self.render_value = render_value

    def get_context(self, name, value, attrs):
        if not self.render_value:
            value = None

        return super().get_context(name, value, attrs)

在templates目录下,创建mail_widget.html文件,内容如下:

<input type="{{ widget.type }}" name="{{ widget.name }}"{% if widget.value != None %} value="{{ widget.value|stringformat:'s' }}"{% endif %} />
</div>
<div style="padding: 5px"  >
    <button type="button"
            style="padding: 5px 10px;
                   border-radius: 5px;
                   background-color:lightblue;"
        onclick="send('{{ widget.value }}')">发送激活邮件</button>

<script>
    function send(email) {
        fetch('/send_mail/'+email+"/")
          .then(resp=>resp.json())
          .then(data=>{
            alert(data.msg);
        })
    }
</script>

2.3 在forms表单中应用

在forms.py的脚本中

class AppUserForm(forms.ModelForm):
    id = forms.CharField(widget=IDWidget,
                         min_length=32, max_length=32,
                         label='主键', disabled=True)

    # 通过widget属性指定自定义widget部件
    email = forms.CharField(required=False,
                            widget=SendEmailButton, 
                            label='邮箱')

三、django中邮件发送

3.1 选择邮箱

在此配置了163的邮箱, 从设置页面中获取到smtp的服务器相关信息

EMAIL_HOST = 'smtp.163.com'
EMAIL_PORT = 25
EMAIL_HOST_USER = 'disenQF@163.com'
EMAIL_HOST_PASSWORD = 'xapython1903'

EMAIL_HOST_PASSWORD 使用了授权码。

3.2 django.core.mail.send_mail()

from django.core.mail import send_mail as send_163_email


def send_mail(request, email):
    print('send_mail', email)

    subtitle = '用户激活通知'
    message = '<html>亲爱的, 注册的用户disen!请先<a href="/">激活的用户</a></html>'

    send_163_email(subtitle, '', html_message=message,
                   from_email='disenQF@163.com',
                   recipient_list=[email])

    return JsonResponse({
        'msg': '发送成功',
        'info': {
            'email': email
        }
    })

3.3 Python原生发送邮件

import smtplib
from email.mime.text import MIMEText
from email.header import Header
def send_message(title, message, receivers):
    client = smtplib.SMTP('smtp.163.com',port=25)
    client.debuglevel = 1

    client.login('disenQF@163.com', 'xapython1903')

    # message = '<html><h3>亲爱的Disen:</h3><p>您注册的用户需要<a href="http://localhost:8080/">激活</a>才能正常使用</p></html>'
    # title = '易果平台-用户激活通知'

    # 第二个参数是内容的类型, html 富文本, plain 文本
    message = MIMEText(message, 'html', 'utf-8')
    message['Subject'] = Header(title, 'utf-8')
    message['From'] = 'disenQF@163.com'
    message['To'] = ','.join(receivers)
	
    client.send_message(message,
                        from_addr='disenQF@163.com',
                        to_addrs=receivers)

    print('---ok--')

【注意】: 554错误, 经常是MIMEText的发送者和接收者的信息与send_message()中的发送者和接收者不匹配。解决的办法:改成一致的。

四、django的跨域请求

五、接口的单元测试(自动化)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值