Django Model Form

本文介绍了Django中ModelForm的使用方法,包括如何结合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>

 

转载于:https://www.cnblogs.com/jonathan1314/p/7510593.html

DjangoModelForm是一种快速创建表单的方式,可以自动生成表单,并且与数据库中的数据模型相对应。使用ModelForm可以大大简化表单的创建和数据的验证。 使用ModelForm需要先定义一个继承自django.forms.ModelForm的类,然后在该类中指定数据模型和要包含的字段。例如: ```python from django import forms from myapp.models import MyModel class MyModelForm(forms.ModelForm): class Meta: model = MyModel fields = ['field1', 'field2', 'field3'] ``` 在上面的代码中,我们创建了一个名为MyModelForm的类,它继承自ModelForm。然后在Meta类中指定了数据模型MyModel和要包含的字段field1、field2、field3。 接下来,我们可以在视图函数中使用该表单来处理用户提交的数据。例如: ```python from django.shortcuts import render from myapp.forms import MyModelForm def my_view(request): if request.method == 'POST': form = MyModelForm(request.POST) if form.is_valid(): # 处理表单数据 form.save() else: form = MyModelForm() return render(request, 'my_template.html', {'form': form}) ``` 在上面的代码中,我们首先判断请求的方法是否为POST,如果是则创建一个MyModelForm的实例,并将POST数据传递给该实例。然后判断表单数据是否有效,如果有效则将数据保存到数据库中。如果请求的方法不是POST,则创建一个空的MyModelForm实例,并将其传递给模板。在模板中,我们可以使用该表单来渲染一个HTML表单,让用户输入数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值