96django_modelform
admin
2023-07-08 12:23:35
0次

 

目录

ModelForm.. 1

Model field与Form field:... 1

ModelForm save()方法:... 4

ModelForm Meta:... 5

ModelForm自定义验证:... 5

ModelForm initial and  instance:... 6

 

 

 

ModelForm

 

结合了form和model,将model的field类型映射成form的field类型,复用了model的验证,还实现了存储数据库的简单方法,写更简洁的代码;

 

django提供一个辅助类(class Meta),使之可从Model创建Form;

生成的Form类中将具有和指定的模型字段对应的表单字段,顺序为fields属性中指定的顺序;

 

 

Model field与Form field:

每个模型字段有一个对应的默认表单字段,如模型中的ManyToManyField对应表单中的ModelMultipleChoiceField,ForeignKey<-->ModelChoiceField;

96django_modelform

 

例:

mysite/books/models.py

TITLE_CHOICE = (

    ('MR', 'Mr.'),

    ('MRS', 'Mrs'),

    ('MS', 'Ms.'),

)

 

class Author(models.Model):

    name = models.CharField(max_length=100)

    title = models.CharField(max_length=3, choice=TITLE_CHOICE)

    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)

 

 

mysite/books/forms.py

from django import forms

from django.forms import ModelForm

from .models import Author, Book

 

class AuthorForm(ModelForm):

    class Meta:

        model = Author

        fields = ['name', 'title', 'birth_date']   #使用model的全部字段,用field = '__all__',另exclude = ('birth_date')排除的字段列表,建议显式的设置,否则有安全问题

 

class BookForm(ModelForm):

    class Meta:

        model = Book

        fields = ['name', 'authors']

 

# from .models import TITLE_CHOICE

# class AuthorForm(forms.Form):

#     name = forms.CharField(max_length=100)

#     title = forms.CharField(max_length=3, widget=forms.Select(choices=TITLE_CHOICE))

#     birth_date = forms.DateField(required=False)

#

# class BookFrom(forms.Form):

#     name = forms.CharField(max_length=100)

#     authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())

 

注:

模型字段blank=True,表单字段require=False;

模型字段verbose_name(首字段大写the first character capitalized),表单字段label;

模型字段help_text,表单字段help_text;

模型字段choices,表单字段widget=forms.Select(choices=TITLE_CHOICE),choices从模型中来,选项通常会包含空选项,且默认会选择,如果字段是必选的,它会强制用户选择一个选项,如果模型字段的default且有一个显示default值,将不会包含空选项(初始值即blank=False);

 

 

ModelForm save()方法:

这个方法根据表单绑定的数据创建并保存数据库对象;

 

save()接受关键字参数commit,book=save(commit=False)时:

1将返回一个还没有保存到数据库的对象,这种情况下,要调用模型实例的form.save(),

2在多对多关系时指定commit=False,django不会立即为多对多有关系保存表单数据(只有实例在数据库中存在时才可保存实例的多对多关系),要手动调用save_m2m()来保存多对多的表单数据

 

save_m2m()仅在save(commit=False)时才用到;

 

 

>>> from publish.models import Author,Book

>>> from publish.forms import AuthorForm,BookForm

>>> form = AuthorForm({'name':'jowin','title':'MR'})

>>> form.is_valid()

True

>>> form.is_bound

True

>>> form.save()   #author=form.save(),后续用返回的对象

 

>>> form = AuthorForm({'name':'mage','title':'MR'})

>>> form.is_valid()

True

>>> form.save()   #author=form.save()

 

>>> authors = Author.objects.all()

>>> authors_id = [author.id for author in authors]

 

>>> form = BookForm({'name':'django book','authors':authors_id})

>>> form.is_valid()

True

>>> form.save()   #book=form.save()

 

>>> form = BookForm({'name':'py book','authors':authors_id})

>>> form.is_valid()

True

>>> form.save()

 

>>> form = BookForm({'name':'js book','authors':authors_id})

>>> form

>>> book = form.save(commit=False)

>>> book

>>> book.name = 'react book'

>>> book.save()

 

>>> form.save_m2m()

>>> book.name

'react book'

 

 

ModelForm Meta:

 

mysite/publish/forms.py

class AuthorForm(ModelForm):

    class Meta:

        model = Author

        fields = ['name', 'title', 'birth_date']   #fields = '__all__';exclude = ('birth_date')

 

        labels = {'name': 'Writer'}

        widgets = {'name': Textarea(attrs={'cols': 80, 'rows': 20})}   #forms.Textarea()

        help_texts = {'name': 'Some useful help text'}

        error_messages = {'name': {'max_length': "This writer's name is too long."}}

 

 

ModelForm自定义验证:

 

mysite/publish/forms.py

class AuthorForm(ModelForm):

    class Meta:

        model = Author

        fields = ['name', 'title', 'birth_date']   #fields = '__all__';exclude = ('birth_date')

 

        labels = {'name': 'Writer'}

        widgets = {'name': Textarea(attrs={'cols': 80, 'rows': 20})}

        help_texts = {'name': 'Some useful help text'}

        error_messages = {'name': {'max_length': "This writer's name is too long."}}

 

        def clean(self):

            cleaned_data = super(AuthorForm, self).clean()

            name = cleaned_data.get('name')

            title = cleaned_data.get('title')

            if len(name) < 40 and title == 'MR':

                raise ValidationError('Field: {} and {} is error'.format(name, title))

 

        def clean_name(self):   #clean_

            name = self.cleaned_data['name']

            if len(name) < 30:

                raise ValidationError('length must more than 30')

            return name

 

 

ModelForm initial and instance:

提供初始值;

 

mysite/publish/views.py   #view中使用modelform

from django.shortcuts import render, get_object_or_404

from django.http import HttpResponse

from .forms import AuthorForm

from .models import Author

 

def index(request):

    if request.method == 'POST':

        form = AuthorForm(request.POST)

        if form.is_valid():

            publish = form.save()

            return HttpResponse('ok')

    else:

        form = AuthorForm()

    return render(request, 'publish/publish.html', {'form': form})

 

def update(request, publish_id):

    author = get_object_or_404(Author, id=publish_id)

    if request.method == 'POST':

        form = AuthorForm(request.POST, instance=author)   #更新时要加instance,否则认为是新创建,也可form=AuthorForm(request.POST,initial={'name':'test'})

        if form.is_valid():

            author = form.save()

            return HttpResponse('add succeed')

    form = AuthorForm(instance=author)   #initial={'name':'test'}

    return render(request, 'publish/publish.html', {'form': form})

 

 

 

mysite/publish/models.py

from django.db import models

 

TITLE_CHOICE = (

    ('MR', 'Mr.'),

    ('MRS', 'Mrs'),

    ('MS', 'Ms.'),

)

 

class Author(models.Model):

    name = models.CharField(max_length=100)

    title = models.CharField(max_length=3, choices=TITLE_CHOICE)

    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)

 

 

 

 


上一篇:97django_model

下一篇:94django_template

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...