Forms#3

作者: wangfp | 来源:发表于2017-09-22 19:46 被阅读0次

    ModelForm

    以已创建的model为原型创建表单时可以继承forms.ModelForm
    大多数model的字段类型都有对应的form字段类型,除了几个比较特殊的字段

    • ForeignKey这个model字段对应着form字段中的ModelChoiceField(其是一个ChoiceField)
    • ManyToManyField字段则对应着form字段中的ModelMultipleChoiceField(其是一个MutipleChoiceField)

    form字段中的一些其它属性:

    • 如果在model fieldblank=True,在form field中会有required=False
    • form field的标签名将会默认为model field中的verbose_name
    • model field中的help_text属性将会被form field使用
    • 如果model field中存在choices参数,form field中将会设置widget=Select
    from django.db import models
    from django.forms import ModelForm
    
    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):              # __unicode__ on Python 2
            return self.name
    
    class Book(models.Model):
        name = models.CharField(max_length=100)
        authors = models.ManyToManyField(Author)
    
    class AuthorForm(ModelForm):
        # 在Meta中指定对应的model和会在表单中可见的字段
        # 可以在Meta中重载error_messages
        class Meta:
            model = Author
            fields = ['name', 'title', 'birth_date']
    
    class BookForm(ModelForm):
        class Meta:
            model = Book
            fields = ['name', 'authors']
    

    上边的ModelForm基本上等同于下边自定义的Form(除了save()方法)

    from django import forms
    
    class AuthorForm(forms.Form):
        name = forms.CharField(max_length=100)
        title = forms.CharField(
            max_length=3,
            widget=forms.Select(choices=TITLE_CHOICES),
        )
        birth_date = forms.DateField(required=False)
    
    class BookForm(forms.Form):
        name = forms.CharField(max_length=100)
        authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())
    

    save()方法

    ModelForm中有一个save()方法,该方法会将表单提交的数据保存到数据库中,并返回一个model实例

    commit关键字参数
    commit参数默认为True,即会自动将表单数据保存入数据库中;
    若将commit设置为False,只会得到一个model实例,而不会向数据库提交,如果需要提交,则利用model实例的save()方法进行提交;
    需要注意的一点是,当model与其他Model存在many-to-many关系时,若设置commit=False,则在对model实例进行save()后,还需要对表单调用save_m2m()方法以提交many-to-many表中的数据

    # Create a form instance with POST data.
    >>> f = AuthorForm(request.POST)
    
    # Create, but don't save the new author instance.
    >>> new_author = f.save(commit=False)
    
    # Modify the author in some way.
    >>> new_author.some_field = 'some_value'
    
    # Save the new instance.
    >>> new_author.save()
    
    # Now, save the many-to-many data for the form.
    >>> f.save_m2m()
    

    选择使用的字段

    官方推荐通过fields来显式地指定需要提交的表单字段,以保证表单提交过程中的安全
    设置field属性的两种快捷方法

    • 使用__all__来声明使用所有的字段
      from django.forms import ModelForm
      
      class AuthorForm(ModelForm):
          class Meta:
              model = Author
              fields = '__all__'
      
    • 设置exclude属性来声明不会使用的字段
      class PartialAuthorForm(ModelForm):
          class Meta:
              model = Author
              exclude = ['title']
      

    重载model中的字段

    可以在ModelForm中改变model字段在表单中的表现形式

    from django.forms import ModelForm, Textarea
    from myapp.models import Author
    
    class AuthorForm(ModelForm):
        class Meta:
            model = Author
            fields = ('name', 'title', 'birth_date')
            # 将model中name列的表现形式由text变为textarea,并指定一些属性
            widgets = {
                'name': Textarea(attrs={'cols': 80, 'rows': 20}),
            }
    

    除此之外,还可以在Meta中重新指定label, help_texterror_messages属性

    from django.utils.translation import ugettext_lazy as _
    
    class AuthorForm(ModelForm):
        class Meta:
            model = Author
            fields = ('name', 'title', 'birth_date')
            # 通过字典来改变属性(键为需要改变的列名)
            labels = {
                'name': _('Writer'),
            }
            help_texts = {
                'name': _('Some useful help text.'),
            }
            error_messages = {
                'name': {
                    'max_length': _("This writer's name is too long."),
                },
            }
    

    Form Asset

    在Media中设置css, js

    相关文章

      网友评论

          本文标题:Forms#3

          本文链接:https://www.haomeiwen.com/subject/jipfextx.html