如何正确使用Django Forms
1个回答
展开全部
1. Django Forms的强大之处
有些django项目并不直接呈现HTML, 二是以API框架的形式存在, 但你可能没有想到, 在这些API形式的django项目中也答洞数用到了django forms. django forms不仅仅是用来呈现HTML的, 他们最强的地方应该是他们的清首验证能力. 下面我们就介绍几种和Django forms结合使用的模式:
2. 模式一: ModelForm和默认验证
最简单的使用模式便是ModelForm和model中定义的默认验证方式的组合:
# myapp/views.py
from django.views.generic import CreateView, UpdateView
from braces.views import LoginRequiredMixin
from .models import Article
class ArticleCreateView(LoginRequiredMixin, CreateView):
model = Article
fields = ('title', 'slug', 'review_num')
class ArticleUpdateView(LoginRequiredMixin, UpdateView):
model = Article
fields = ('title', 'slug', 'review_num')
正如以上代码中看到的一样:
ArticleCreateView和ArticleUpdateView中设置model为Article
两个view都基于Article model自动生成了ModelForm
这些ModelForm的验证, 是基于Article model中定义的field转换而来的
3. 模式二, 在ModelForm中修改验证
在上面的例子中, 如果我们希望每篇article title的颤唤开头都是"new", 那么应该怎么做呢? 首先我们需要建立自定义的验证(validator):
# utils/validator.py
from django.core.exceptions import ValidationError
def validate_begins(value):
if not value.startswith(u'new'):
raise ValidationError(u'Must start with new')
可见, 在django中的验证程序就是不符合条件便抛出ValidationError的function, 为了方便重复使用, 我们将它们放在django app utils的validators.py中.
接下来, 我们可以在model中加入这些validator, 但为了今后的方便修改和维护, 我们更倾向于加入到ModelForm中:
# myapp/forms.py
from django import forms
from utils.validators import validate_begin
from .models import Article
class ArticleForm(forms.ModelForm):
dev __init__(self, *args, **kwargs):
super(ArticleForm, self).__init__(8args, **kwargs)
self.fields["title"].validators.append(validate_begin)
class Meta:
model = Article
Django的edit views(UpdateView和CreateView等)的默认行为是根据view中model属性, 自动创建ModelForm. 因此, 我们需要调用我们自己的Modelform来覆盖自动创建的:
# myapp/views.py
from django.views.generic import CreateView, UpdateView
from braces.views import LoginRequiredMixin
from .models import Article
from .forms import ArticleForm
class ArticleCreateView(LoginRequiredMixin, CreateView):
model = Article
fields = ('title', 'slug', 'review_num')
form_class = ArticleForm
class ArticleUpdateView(LoginRequiredMixin, UpdateView):
model = Article
fields = ('title', 'slug', 'review_num')
form_class = ArticleForm
4. 模式三, 使用form的clean()和clean_<field>()方法
如果我们希望验证form中的多个field, 或者验证涉及到已经存在之后的数据, 那么我们就需要用到form的clean()和clean_<field>&()方法了. 以下代码检查密码长度是否大于7位, 并且password是否和password2相同:
# myapp/forms.py
from django import forms
class MyUserForm(forms.Form):
username = forms.CharField()
password = forms.CharField()
password2 = forms.CharField()
def clean_password(self):
password = self.cleaned_data['password']
if len(password) <= 7:
raise forms.ValidationError("password insecure")
return password
def clean():
cleaned_data = super(MyUserForm, self).clean()
password = cleaned_data.get('password', '')
password2 = cleaned_data.get('password2', '')
if password != password2:
raise forms.ValidationError("passwords not match")
return cleaned_data
其中需要注意的是, clean()和clean_<field>&()的最后必须返回验证完毕或修改后的值.
5. 模式四, 自定义ModelForm中的field
我们会经常遇到在form中需要修改默认的验证, 比如一个model中有许多非必填项, 但为了信息完整, 你希望这些field在填写时是必填的:
# myapp/models.py
from django.db import models
class MyUser(models.Model):
username = models.CharField(max_length=100)
password = models.CharField(max_length=100)
address = models.TextField(blank=True)
phone = models.CharField(max_length=100, blank=True)
为了达到以上要求, 你可能会通过直接增加field改写ModelForm:
# 请不要这么做
# myapp/forms.py
from django import forms
from .models import MyUser
class MyUserForm(forms.ModelForm):
# 请不要这么做
address = forms.CharField(required=True)
# 请不要这么做
phone = forms.CharField(required=True)
class Meta:
model = MyUser
请不要这么做, 因为这违反"不重复"的原则, 而且经过多次的拷贝粘贴, 代码会变得复杂难维护. 正确的方式应当是利用__init__():
# myapp/forms.py
from django import forms
from .models import MyUser
class MyUserForm(forms.ModelForm):
def __init__(self, *args, **kwarg):
super(MyUserForm, self).__init__(*args, **kwargs)
self.fields['address'].required = True
self.fields['phone'].required = True
class Meta:
model = MyUser
值得注意的是, Django forms也是Python类, 类可以继承和被继承, 也可以动态修改.
有些django项目并不直接呈现HTML, 二是以API框架的形式存在, 但你可能没有想到, 在这些API形式的django项目中也答洞数用到了django forms. django forms不仅仅是用来呈现HTML的, 他们最强的地方应该是他们的清首验证能力. 下面我们就介绍几种和Django forms结合使用的模式:
2. 模式一: ModelForm和默认验证
最简单的使用模式便是ModelForm和model中定义的默认验证方式的组合:
# myapp/views.py
from django.views.generic import CreateView, UpdateView
from braces.views import LoginRequiredMixin
from .models import Article
class ArticleCreateView(LoginRequiredMixin, CreateView):
model = Article
fields = ('title', 'slug', 'review_num')
class ArticleUpdateView(LoginRequiredMixin, UpdateView):
model = Article
fields = ('title', 'slug', 'review_num')
正如以上代码中看到的一样:
ArticleCreateView和ArticleUpdateView中设置model为Article
两个view都基于Article model自动生成了ModelForm
这些ModelForm的验证, 是基于Article model中定义的field转换而来的
3. 模式二, 在ModelForm中修改验证
在上面的例子中, 如果我们希望每篇article title的颤唤开头都是"new", 那么应该怎么做呢? 首先我们需要建立自定义的验证(validator):
# utils/validator.py
from django.core.exceptions import ValidationError
def validate_begins(value):
if not value.startswith(u'new'):
raise ValidationError(u'Must start with new')
可见, 在django中的验证程序就是不符合条件便抛出ValidationError的function, 为了方便重复使用, 我们将它们放在django app utils的validators.py中.
接下来, 我们可以在model中加入这些validator, 但为了今后的方便修改和维护, 我们更倾向于加入到ModelForm中:
# myapp/forms.py
from django import forms
from utils.validators import validate_begin
from .models import Article
class ArticleForm(forms.ModelForm):
dev __init__(self, *args, **kwargs):
super(ArticleForm, self).__init__(8args, **kwargs)
self.fields["title"].validators.append(validate_begin)
class Meta:
model = Article
Django的edit views(UpdateView和CreateView等)的默认行为是根据view中model属性, 自动创建ModelForm. 因此, 我们需要调用我们自己的Modelform来覆盖自动创建的:
# myapp/views.py
from django.views.generic import CreateView, UpdateView
from braces.views import LoginRequiredMixin
from .models import Article
from .forms import ArticleForm
class ArticleCreateView(LoginRequiredMixin, CreateView):
model = Article
fields = ('title', 'slug', 'review_num')
form_class = ArticleForm
class ArticleUpdateView(LoginRequiredMixin, UpdateView):
model = Article
fields = ('title', 'slug', 'review_num')
form_class = ArticleForm
4. 模式三, 使用form的clean()和clean_<field>()方法
如果我们希望验证form中的多个field, 或者验证涉及到已经存在之后的数据, 那么我们就需要用到form的clean()和clean_<field>&()方法了. 以下代码检查密码长度是否大于7位, 并且password是否和password2相同:
# myapp/forms.py
from django import forms
class MyUserForm(forms.Form):
username = forms.CharField()
password = forms.CharField()
password2 = forms.CharField()
def clean_password(self):
password = self.cleaned_data['password']
if len(password) <= 7:
raise forms.ValidationError("password insecure")
return password
def clean():
cleaned_data = super(MyUserForm, self).clean()
password = cleaned_data.get('password', '')
password2 = cleaned_data.get('password2', '')
if password != password2:
raise forms.ValidationError("passwords not match")
return cleaned_data
其中需要注意的是, clean()和clean_<field>&()的最后必须返回验证完毕或修改后的值.
5. 模式四, 自定义ModelForm中的field
我们会经常遇到在form中需要修改默认的验证, 比如一个model中有许多非必填项, 但为了信息完整, 你希望这些field在填写时是必填的:
# myapp/models.py
from django.db import models
class MyUser(models.Model):
username = models.CharField(max_length=100)
password = models.CharField(max_length=100)
address = models.TextField(blank=True)
phone = models.CharField(max_length=100, blank=True)
为了达到以上要求, 你可能会通过直接增加field改写ModelForm:
# 请不要这么做
# myapp/forms.py
from django import forms
from .models import MyUser
class MyUserForm(forms.ModelForm):
# 请不要这么做
address = forms.CharField(required=True)
# 请不要这么做
phone = forms.CharField(required=True)
class Meta:
model = MyUser
请不要这么做, 因为这违反"不重复"的原则, 而且经过多次的拷贝粘贴, 代码会变得复杂难维护. 正确的方式应当是利用__init__():
# myapp/forms.py
from django import forms
from .models import MyUser
class MyUserForm(forms.ModelForm):
def __init__(self, *args, **kwarg):
super(MyUserForm, self).__init__(*args, **kwargs)
self.fields['address'].required = True
self.fields['phone'].required = True
class Meta:
model = MyUser
值得注意的是, Django forms也是Python类, 类可以继承和被继承, 也可以动态修改.
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询