如何正确使用 Django Forms

 我来答
greystar_cn
2018-07-06 · 知道合伙人软件行家
greystar_cn
知道合伙人软件行家
采纳数:16407 获赞数:17260
本人主要从事.NET C#方向的技术开发工作,具有10多年的各类架构开发工作经验。

向TA提问 私信TA
展开全部
Django forms使用容易, 又方便扩展, 因此Django admin和CBVs基本都基于forms使用. 事实上, 由于django forms的强大验证功能, 大多数Django API 框架都是用forms作为其验证的一部分.

虽然django forms的学习需要花费一点时间, 但如果将forms, models和views结合起来使用, 我们可以花费很少的经历来完成庞大的工作.

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):
厉害981
推荐于2016-06-16 · TA获得超过4万个赞
知道大有可为答主
回答量:1.4万
采纳率:85%
帮助的人:3462万
展开全部
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类, 类可以继承和被继承, 也可以动态修改.
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
老夭来了
2015-01-30 · 知道合伙人软件行家
老夭来了
知道合伙人软件行家
采纳数:1806 获赞数:8100
2008年从事软件开发,拥有多年的python,php,linux工作经验,发布过多个python,php的开源项目。

向TA提问 私信TA
展开全部
Django forms使用容易, 又方便扩展, 因此Django admin和CBVs基本都基于forms使用. 事实上, 由于django forms的强大验证功能, 大多数Django API 框架都是用forms作为其验证的一部分.
最简单的使用模式便是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转换而来的

如果解决了您的问题请采纳!
如果未解决请继续追问!
本回答被提问者和网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式