Django ModelForm 组件的应用

ModelForm组件的应用

ModelForm 组件的创建: 

1.创建一个,该类继承 forms.ModelForm 

2.大致组成部分

class ModelNameModelForm(forms.ModelForm):

  class Meta:

    model =需要校正的模型类名

    例:model = models.Book

    fields=" __all__"  或  fields=["字段名”,........]    选择需要展示或校正的字段

    error_messages={

      "字段名”:{“required”: "此字段不能为空”},

      "字段名”:{“required”: "此字段不能为空”},

       .........

       }

    from django.forms import  widgets as wid

    widgets={

        "字段名":wid.TextInput(attrs={"input标签属性":"属性值"}),

        "price":wid.TextInput(attrs={"class":"form-control"}),

        "pub_date":wid.DateInput(attrs={"class":"form-control","type":"date"}),

      }

    labels={

        "字段名”:“别名”,

        “title” :“书籍名称”,

        }

    #钩子,进一步校正函数

  def  clean_字段名(self)

    val = self.cleaned_data.get("字段名”)

    if  符合条件:

      return  val

    else:

      raise  ValidationError("想要说明的错误信息”)

3.应用

用的时候只需要  :

form = ModelNameModelForm(需要校正的数据字典)

例:

1.直接展示空的input的标签(get请求时)

form = BookModelForm( )   #直接展示,渲染出空内容的input 标签 

#  form = BookModelForm(instance=edit_book)   编辑情况下

2.用户提交数据,需校正时,可以展示错误的提示信息 (post请求时)

form = BookModelForm(request.POST )    #校正前端通过post请求的提交的数据 

##form = BookModelForm(request.POST,instance=edit_book)   编辑情况下

if  form.is_vaild():

  form.save()

  redirect("/book/")

else:

  return render(request, 'addbook.html', locals())

实例

1.model .py :(模型类  Book为例)

from django.db import models

# Create your models here.
from django.db import models

# Create your models here.
class Book(models.Model):
    title = models.CharField( max_length=32,verbose_name="书籍名称")
    pub_date=models.DateField(verbose_name="出版日期")
    price=models.DecimalField(max_digits=5,decimal_places=2,verbose_name="价格")
    publish=models.ForeignKey(to="Publish",to_field="id",on_delete=models.CASCADE,null=True,verbose_name="出版社")
    authors=models.ManyToManyField("Author",db_table="book2authors",verbose_name="作者") # 创建关系表
    def __str__(self):
        return self.title

    class Meta:
        verbose_name="书籍"

2.views.py(构建ModelForm组件)

 
 

 form django import  forms

 from django.forms import  widgets as wid

from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
class BookModelForm(forms.ModelForm):
    class Meta:
        model = models.Book
        fields="__all__" #默认页面渲染时 显示所有的字段
        # fields=["title","price"] #需要显示的字段 

     #错误信息 error_messages={ "title":{"required":"书名不能为空"}, "price":{"required":"价格不能为空"}, "pub_date":{"required":"日期不能为空"}, "publish":{"required":"出版社不能为空"}, "authors":{"required":"作者不能为空"}, }

     #给渲染的input标签设置type类型和相关的属性

widgets
={ "title":wid.TextInput(attrs={"class":"form-control"}), "price":wid.TextInput(attrs={"class":"form-control"}), "pub_date":wid.DateInput(attrs={"class":"form-control","type":"date"}), }

     #字段别名设置 labels
={ "title":"书籍名称",
        }
  #钩子函数,进一步进行约束
   #对title字段进行约束
def clean_title(self): val=self.cleaned_data.get("title") if val.isdigit(): raise ValidationError("书名不能为纯数字!") else: return val

  #对price字段进行约束
  def clean_price(self):
    val=self.cleaned_data.get("price")
    if val.isdigit():
      return val
    else:
      raise ValidationError("价格必须为数字")

3.views.py视图函数中:

后端添加视图函数:用ModelForm组件实现页面渲染 (红色字体部分)

def addbook(request):
    if request.method=="POST":
        '''
            data=request.POST.dict()
            data.pop("csrfmiddlewaretoken")
            data.pop("author_list")
            book=models.Book.objects.create(**data)  #  保证提交键值对的键必须和数据库表字段一致
            #  为书籍绑定作者关系
            author_list=request.POST.getlist("author_list")
            print(author_list) # ['1', '2']
            book.authors.add(*author_list)
          
        '''
        form=BookModelForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect("/books/")
        else:
            return render(request, 'addbook.html', locals())


    else:

        # form=BookForm()   # forms组件
        form=BookModelForm()       #  modelforms组件
        return render(request,'addbook.html',locals())

前端添加页面:

<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h3>添加{{ table_name }}</h3>
            <form action="" method="post" novalidate>
                {% csrf_token %}
                {% for field in form %}
                    <div>
                        <label for="">{{ field.label }}</label>
                        {{ field }}<span class="error pull-right">{{ field.errors.0 }}</span>
                    </div>
                {% endfor %}
                <input type="submit" class="btn btn-primary">

            </form>
        </div>
    </div>
</div>

后端编辑视图:

def editbook(request,edit_book_id):
    edit_book = models.Book.objects.filter(pk=edit_book_id).first()
    if request.method=="POST":
        # 方式1:
        # title=request.POST.get("title")
        # price=request.POST.get("price")
        # pub_date=request.POST.get("pub_date")
        # publish_id=request.POST.get("publish_id")
        # author_list=request.POST.getlist("author_list")
        # models.Book.objects.filter(pk=edit_book_id).update(title=title,price=price,pub_date=pub_date,publish_id=publish_id)  # update只有queryset才能调用
        # edit_book.authors.set(author_list)

        #  方式2:

        # data=request.POST.dict()
        # data.pop("csrfmiddlewaretoken")
        # author_list=data.pop("author_list")
        # models.Book.objects.filter(pk=edit_book_id).update(**data)  #  保证提交键值对的键必须和数据库表字段一致
        # #  为书籍绑定作者关系
        # author_list=request.POST.getlist("author_list")
        # edit_book.authors.set(author_list)

        # 方式3
        form = BookModelForm(request.POST,instance=edit_book)#编辑时,instance=edit_book 传进去就可以该对象信息在页面的展示,这是编辑和添加页面的区别之处
        if form.is_valid():,
            form.save()
            return redirect("/books/")
        else:
            return render(request, 'editbook.html', locals())

    else:

        form=BookModelForm(instance=edit_book)
        return render(request,'editbook.html',locals())

前端编辑页面渲染代码:

<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h3>编辑{{ table_name }}</h3>
            <form action="" method="post" novalidate>
                {% csrf_token %}
                {% for field in form %}
                    <div>
                        <label for="">{{ field.label }}</label>
                        {{ field }}<span class="error pull-right">{{ field.errors.0 }}</span>
                    </div>
                {% endfor %}
                <input type="submit" class="btn btn-primary">

            </form>
        </div>
    </div>
</div>

    

猜你喜欢

转载自www.cnblogs.com/knighterrant/p/10279659.html