forms组件钩子函数

钩子函数可以让字段在原有的校验功能上在新增一个自定义校验的功能。

局部钩子

校验单个字段,在form类中编写一个函数:

def clean_字段名(self):
    校验代码
    return 字段值

比如:判断用户名name字段值是否存在:

class LoginForm(forms.Form):
    name = forms.CharField(max_length=8)

    def clean_name(self):
        # 先获取字段值
        name = self.clean_data.get('name')
        # 判断是否存在
        is_exist = models.User.objects.filter(name=name)
        if is_exist:
            # 错误信息展示
            self.add_error('name', '用户名已存在')
        # 最后将你勾上来的name返回回去
        return name

全局钩子

校验多个字段,在form类中编写一个函数:

def clean(self):
    校验代码
    return self.cleaned_data

比如校验两个字段值是否一致:

class LoginForm(forms.Form):
    name = forms.CharField(max_length=8)
    confirm_name = forms.CharField(max_length=8)

    def clean(self):
        # 先获取字段值
        name = self.clean_data.get('name')
        confirm_name = self.clean_data.get('confirm_name')
        # 判断是否一致
        if name != confirm_name:
            # 错误信息展示
            self.add_error('confirm_name', '两次用户名不一致')
        # 最后将整个数据返回
        return self.clean_data

forms组件补充与ModelForm简单使用与cookie与session-LMLPHP

forms组件字段参数

字段参数

validators详解

演示:

from django.core.validators import RegexValidator
class MyForm(forms.Form):
    phone = forms.CharField(
        validators=[
            RegexValidator(r'^[0-9]+$', '请输入数字'),
            RegexValidator(r'^159[0-9]+$', '数字必须以159开头')
        ]
    )

choices详解

定义选择类型的标签内部对应关系,可以直接编写,也可以从数据库中获取。

方式一:

# 直接编写
class MyForm(forms.Form):
    gender = forms.fields.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "保密")),
        label="性别",
    )

# 数据库获取数据
class MyForm(forms.Form):
    course = forms.fields.ChoiceField(
        choices=models.Course.objects.all().values_list('id', 'name'),
        label="课程",
    )

方式二:

# 直接编写
class MyForm(forms.Form):
    gender = forms.fields.ChoiceField(label="性别")

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['gender'].choices = ((1, "男"), (2, "女"), (3, "保密"))

# 数据库获取数据
class MyForm(forms.Form):
    course = forms.fields.ChoiceField(label="课程")

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['course'].choices = models.Course.objects.all().values_list('id', 'name')

widget详解

使用form组件生成的标签无法在前端自定义样式,只能使用widget来控制。

基本语法:

widgets=forms.widgets.控制type的类型(
    attrs={'属性1':'值',...}
)

比如:

class MyForm(forms.Form):
    name = forms.CharField(
        widget=forms.widgets.TextInput(
            attr={'class':'c1'}
        )
    )

文本输入框

widget=forms.widgets.TextInput()

密码输入框

widget=forms.widgets.PasswordInput()

数字输入框

widget=forms.widgets.NumberInput()

radio

class MyForm(forms.Form):
    gender = forms.fields.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "保密")),
        label="性别",
        widget=forms.widgets.RadioSelect()
    )

单选select

class MyForm(forms.Form):
    gender = forms.fields.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "保密")),
        label="性别",
        widget=forms.widgets.Select()
    )

多选select

class MyForm(forms.Form):
    hobby = forms.fields.MultipleChoiceField(
        choices=((1, "read"), (2, "run"), (3, "game")),
        label="爱好",
        widget=forms.widgets.SelectMultiple()
    )

单选checkbox

class MyForm(forms.Form):
    keep = forms.ChoiceField(
        label="是否记住密码",
        widget=forms.widgets.CheckboxInput()
    )

多选checkbox

class MyForm(forms.Form):
    hobby = forms.fields.MultipleChoiceField(
        choices=((1, "read"), (2, "run"), (3, "game")),
        label="爱好",
        widget=forms.widgets.CheckboxSelectMultiple()
    )

forms组件补充与ModelForm简单使用与cookie与session-LMLPHP

forms组件字段类型

常见字段

其他字段

ModelForm简单使用

forms组件主要配合models里面的模型类一起使用,但是模型类里面的字段需要在forms类中相当于重写一遍,代码冗余,为了更好的结合forms与models的关系,有了一个ModelForm(基于forms组件)。

简单使用

models:

class User(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    addr = models.CharField(max_length=32)

forms:

class MyUser(forms.ModelForm):
    class Meta:
        model = models.User  # 指定关联的表
        fields = '__all__'  # 所有的字段全部生成对应的forms字段
        labels = {  # 每个字段标签的labels参数
            'name': '用户名',
            'age': '年龄',
            'addr': '地址'
        }
        widgets = {  # 每个字段标签的widget参数
            "name": forms.widgets.TextInput(attrs={"class": "form-control"}),
        }

views:

添加数据

def home(request):
    form_obj = MyUser()
    if request.method == 'POST':
        if form_obj.is_valid():
            # 获取提交的数据
            form_obj = MyUser(request.POST)
            # 保存数据,向表中添加数据
            form_obj.save()
    return render(request, 'home.html', locals())

编辑数据

def home(request):
    form_obj = MyUser()
    if request.method == 'POST':
        if form_obj.is_valid():
            # 获取数据看看是否已存在
            edit_obj = models.User.objects.filter(name=request.POST.get('name')).first()
            # 新增还是保存就取决于instance参数有没有值
            form_obj = MyUser(request.POST,instance=edit_obj)
            # 保存数据
            form_obj.save()
    return render(request, 'home.html', locals())

cookie与session简介

cookie

简介

HTTP协议中有一个特性:无状态,意思是服务端不会保存客户端的数据,客户端一直向服务端发送请求,服务端都不会认识客户端,而cookie就可以让服务端认识客户端。

cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息。

比如在一些网站中,你登陆后就不需要在登录了,这就是因为你的信息被保存在了cookie中,登录一次后,那些网站就知道你已经登录了。

原理

由服务器产生内容,浏览器收到后保存在cookie;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁”了。

forms组件补充与ModelForm简单使用与cookie与session-LMLPHP

session

简介

如果数据保存在cookie中,很容易被看到,安全性太低,因此需要一个新东西,那就是session。它把数据保存在了服务端,并给客户端返回一个随机字符串保存,这个随机字符串与服务端里的数据对应。每次客户端发送请求时会携带该随机字符串,服务端会进行比对。

django操作cookie

基本使用

设置cookie

def index(request):
    res = HttpResponse('index页面')
    res.set_cookie('name', 'abcd')
    return res

获取cookie

def home(request):
    if request.COOKIE.get('name'):
        return HttpResponse('cookie有name')
    return HttpResponse('cookie中没有name')

forms组件补充与ModelForm简单使用与cookie与session-LMLPHP

进阶

在上述例子中,如果我想要给多个视图函数添加一个判断cookie的功能,我们可以使用装饰器:

def login_auth(func):
    def inner(request, *args, **kwargs):
        if request.COOKIES.get('name'):
            return func(request, *args, **kwargs)
        return HttpResponse('你的cookie中还没有name')
    return inner
05-24 09:52