Jonathan1314

导航

Django Model Form

ModelForm

ModelForm结合了Form和Model,将models的field类型映射成forms的field类型,复用了Model和Model验证,

写更少的代码,并且还实现了存储数据库的简单方法

 

models field类型和forms field类型映射关系

https://docs.djangoproject.com/en/1.11/topics/forms/modelforms/#field-types

from django.db import models
from django.forms import ModelForm
from django import forms
from django.utils.translation import ugettext_lazy as _

TITLE_CHOICES = (
    ('MR', 'Mr.'),
    ('MRS', 'Mrs.'),
    ('MS', 'Ms.'),
)


class Author(models.Model):
    name = models.CharField(max_length=100)
    title = models.CharField(max_length=3, choices=TITLE_CHOICES)
    birth_date = models.DateField(blank=True, null=True)

    def __str__(self):
        return self.name


class Book(models.Model):
    name = models.CharField(max_length=100)
    authors = models.ManyToManyField('Author')

    def __str__(self):
        return self.name


class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = ['name', 'title', 'birth_date']


class BookForm(ModelForm):
    class Meta:
        model = Book
        fields = ['name', 'authors']

 

ModelForm save()方法

form.is_valid()之后,form.save()可以直接保存到数据库

 

Django ModelForm Meta

用来配置前端模板的各种选项,可以和Form对应起来,labels、widgets、help_texts、error_messages等,复数形式

class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = ['name', 'title', 'birth_date']
        # fields = '__all__'
        # exclude = ('birth_date',)
        labels = {
            'name': 'Writer',
        }
        widgets = {
            'name': forms.Textarea(attrs={'cols': 80, 'row':20})
        }
        help_texts = {
            'name': _('Some useful help text')  # 需要翻译文件
        }
        error_messages = {
            'name':{
                'max_length':_("This writer's name is too long.")
            },
        }

 

Django ModelForm 自定义验证

先进行 class Meta中的Model验证,在进行每个字段 clean_name()验证,最后进行clean()验证

class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = ['name', 'title', 'birth_date']

    # 校验单个字段
    def clean_name(self):
        name = self.cleaned_data['name']  # 获取数据
        if len(name) < 30:
            raise ValidationError("Length must be more than 30") # 非法时,抛出异常
        return name # 返回该字段值

    # 多个字段联合校验
    def clean(self):
        clean_data = super(AuthorForm, self).clean()
        name = clean_data.get('name')
        title = clean_data.get('title')
        if len(name) < 40 and title == "MR":
            raise ValidationError('xxxx')   # 对应 form.non_field_errors

 

view和模板中使用 Model Form(最佳实践)

# form.py
class Publisher(models.Model):
    name = models.CharField(max_length=30)
    address = models.CharField(max_length=50)
    city = models.CharField(max_length=60)
    state_province = models.CharField(max_length=30)
    country = models.CharField(max_length=50)
    website = models.URLField()

    def __str__(self):
        return self.name

class PublisherForm(ModelForm):
    class Meta:
        model = Publisher
        # fields = ['name', 'address', 'city', 'state_province', 'country', 'website']
        # fields = '__all__'
        fields = "__all__"

# veiws.py
def publisher_add2(request):
    if request.method == "POST":
        form = PublisherForm(request.POST)
        if form.is_valid():
            publisher = form.save()
            return HttpResponse('添加成功')
    else:
        form = PublisherForm()
        return render(request, 'books2/publisher_add.html', {'form': form })

# books/templates/publish_add.html
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Submit"/>
</form>

POST:

  • form = PublisherForm(request.POST)
  • form.is_valid()
  • form.save()

GET:

  • form = PublisherForm()

 

Django Model Form inital and instance

model中default='中国' 可以在数据库的层面设置默认值,前端是可以正常显示默认值的

form = PublisherForm(initial={'city':'北京'}),在view 层面设置默认值,字段层面

publisher = get_object_or_404(Publisher, id=publisher_id); form = PublisherForm(instance=publisher),默认值是整个对象

form = PublisherForm(request.POST, instance=publisher),更新数据时,request.POST满足条件时更新;不满足条件时还是原来publisher

# views.py
def publisher_update(request, publisher_id):
    publisher = get_object_or_404(Publisher, pk=publisher_id)

    if request.method == "POST":
        form = PublisherForm(request.POST, instance=publisher)
        if form.is_valid():
            publisher = form.save()
            return HttpResponse('更新成功')

    form = PublisherForm(instance=publisher)
    return render(request, 'books2/publisher_update.html', {'form':form})

 

Django form bootstrap 插件

参考链接:

https://github.com/dyve/django-bootstrap3

安装:

pip  install  -i  https://pypi.doubanio.com/simple/  --trusted-host pypi.doubanio.com django-bootstrap3

使用:

{% load bootstrap3 %}

<div class="container">
    <form method="post">
    {% csrf_token %}
    {% bootstrap_form form %}
    {% buttons %}
        <button type="submit" class="btn btn-primary">{% bootstrap_icon "star" %} Submit</button>
    {% endbuttons %}
</form>
</div>

 

posted on 2017-09-13 15:00  Jonathan1314  阅读(358)  评论(0编辑  收藏  举报