《Django By Example》

Django | Part4-Authentication学习笔

2018-03-24  本文已影响5人  寒食君

教程地址
做完Part4,再慢慢回顾,有以下两点是比较有感受的。

封装

在Part4中,我感受到了Django非常高的封装性,我个人觉得从一个学习者的角度出发,这是弊大于利的(比如我首次接触Django)
如果是以快速搭建一个网站为目的,节省开发周期和成本,那封装得越高越好,随手拿来用就是了,多么方便高效。
但是对于初学者,这虽然降低了了学习难度,但是增加了理解难度,也不太利于去拓展Web开发的深度。

class UserCreationForm(forms.ModelForm):
    """
    A form that creates a user, with no privileges, from the given username and
    password.
    """
    error_messages = {
        'password_mismatch': _("The two password fields didn't match."),
    }
    password1 = forms.CharField(
        label=_("Password"),
        strip=False,
        widget=forms.PasswordInput,
        help_text=password_validation.password_validators_help_text_html(),
    )
    password2 = forms.CharField(
        label=_("Password confirmation"),
        widget=forms.PasswordInput,
        strip=False,
        help_text=_("Enter the same password as before, for verification."),
    )

    class Meta:
        model = User
        fields = ("username",)
        field_classes = {'username': UsernameField}

    def __init__(self, *args, **kwargs):
        super(UserCreationForm, self).__init__(*args, **kwargs)
        if self._meta.model.USERNAME_FIELD in self.fields:
            self.fields[self._meta.model.USERNAME_FIELD].widget.attrs.update({'autofocus': True})

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError(
                self.error_messages['password_mismatch'],
                code='password_mismatch',
            )
        self.instance.username = self.cleaned_data.get('username')
        password_validation.validate_password(self.cleaned_data.get('password2'), self.instance)
        return password2

    def save(self, commit=True):
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user

看到这里我就有一个疑惑,Django作为一个后端框架,是将表单传到后台再进行验证,而这部分一般来说往往是通过客户端的Js来操作,Django这样不是很影响效率和浪费带宽吗?

在需要使用到邮箱字段时,教程引入了「继承」的概念,这里也出现了一出因为封装程度很高而引起的理解难点:

class SignUpForm(UserCreationForm):
    email = forms.CharField(max_length=254, required=True, widget=forms.EmailInput())
    class Meta:
        model = User
        fields = ('username', 'email', 'password1', 'password2')

考虑到代码的复用性以及耦合性,教程作者这里使用了fields = ('username', 'email', 'password1', 'password2'),这很好
但是下面在控制器中:

def signup(request):
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            user = form.save()
            auth_login(request, user)
            return redirect('home')
    else:
        form = SignUpForm()
    return render(request, 'signup.html', {'form': form})

直接通过user = form.save()获取了新对象,这很神奇。

测试

首先一点,测试系统会自动在任何以test开头的文件中寻找测试方法,当测试方法越来越多时,需要分模块来组织。

对于初学者来说,测试方法能看懂,也能理解其重要性,但是若要自己独立去写,是有一定难度的,首先是考虑不到那么周全,第二个是熟练度的问题。这需要锻炼。

比如以下几个用来检验返回值的api,就比较眼花缭乱了。

self.assertEquals() //检查字符串
self.assertContains //检查是否包含
self.assertIsInstance() //检查对象类型
self.assertRedirects() //检查是否重定向
self.assertTrue() //检查是否为真
self.assertFalse() //检查是否为假
等等

抛开其他优点,我觉得现阶段测试最直接的好处是:分批次测试,缩小寻找bug的内容,可以最直接地定位错误。而假如不用测试,在运行报错时,需要从一堆报错信息中去慢慢抽丝剥茧,反而影响效率。对测试地总结就是:磨刀不误砍柴工。

公众号:果核里的图灵

<center>小白的探索之路</center>

上一篇 下一篇

猜你喜欢

热点阅读