前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >33.Django ModelForm

33.Django ModelForm

作者头像
zhang_derek
发布2018-04-11 13:23:04
1.4K0
发布2018-04-11 13:23:04
举报
文章被收录于专栏:有趣的django有趣的django

ModelForm

 1.ModeForm简单验证

代码语言:javascript
复制
from django.db import models

# Create your models here.

class UserInfo(models.Model):
    # verbose_name 等同于Form类里面的label
    username = models.CharField(verbose_name='用户',max_length=32)
    email = models.EmailField(verbose_name='邮件')
    user_type = models.ForeignKey(verbose_name='类型',to='UserType',to_field='id')


class UserType(models.Model):
    caption = models.CharField(max_length=32)

    def __str__(self):          #打印名称,不写显示的是obj对象
        return self.caption

models.py
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/index/" method="post">
        {% csrf_token %}
        {{ obj.as_p }}
        <input type="submit" value="提交"/>
    </form>

</body>
</html>

index.html

views.py

代码语言:javascript
复制
from django.shortcuts import render,redirect
from app01 import models
from django import forms
from django.forms import fields

class UserInfoModelForm(forms.ModelForm):
    class Meta:
        model = models.UserInfo  # 去UserInfo类中获取数据
        fields = '__all__'  # __all__ 代指所有字段
        # fields = ['username','email']       #指定显示的字段
        # exclude = ['username']      #不显示的字段

def index(request):
    if request.method == 'GET':
        obj = UserInfoModelForm()
        return render(request,'index.html',{'obj':obj})
    elif request.method == 'POST':
        obj = UserInfoModelForm(request.POST)
        result = obj.is_valid()
        if result:
            print(obj.cleaned_data)             #如果models里没有__str__方法,则user_type获取
                                                        #到的是一个对象,可直接根据对象进行操作
            print(obj.cleaned_data['user_type'])
            # {'username': 'James', 'user_type': < UserType: 超级用户 >, 'email': 'ffd@fdsf.com'}
            # 超级用户
        else:
            print(obj.errors)
        return render(request,'index.html',{'obj':obj})

注:ModelForm最终继承了BaseForm,BaseForm里面具有is_valid方法,所以ModelForm也可以用is_valid进行验证

 2.ModelForm组件

代码语言:javascript
复制
ModelForm
    a.  class Meta:
            model,                           # 对应Model的
            fields=None,                     # 字段
            exclude=None,                    # 排除字段 
            labels=None,                     # 提示信息  labels ={'username':'用户名'}可写多个
            help_texts=None,                 # 帮助提示信息    help_texts = {'username':'help info'}
            widgets=None,                    # 自定义插件
            error_messages=None,             # 自定义错误信息(整体错误信息from django.core.exceptions import NON_FIELD_ERRORS)
            field_classes=None               # 自定义字段类 (也可以自定义字段)
            localized_fields=('birth_date',) # 本地化,如:根据不同时区显示数据
            如:
                数据库中
                    2016-12-27 04:10:57
                setting中的配置
                    TIME_ZONE = 'Asia/Shanghai'
                    USE_TZ = True
                则显示:
                    2016-12-27 12:10:57
    b. 验证执行过程
        is_valid -> full_clean -> 钩子 -> 整体错误
 
    c. 字典字段验证
        def clean_字段名(self):
            # 可以抛出异常
            # from django.core.exceptions import ValidationError
            return "新值"
    d. 用于验证
        model_form_obj = XXOOModelForm()
        model_form_obj.is_valid()
        model_form_obj.errors.as_json()
        model_form_obj.clean()
        model_form_obj.cleaned_data
    e. 用于创建
        model_form_obj = XXOOModelForm(request.POST)
        #### 页面显示,并提交 #####
        # 默认保存多对多
            obj = form.save(commit=True)
        # 不做任何操作,内部定义 save_m2m(用于保存多对多)
            obj = form.save(commit=False)
            obj.save()      # 保存单表信息
            obj.save_m2m()  # 保存关联多对多信息
 
    f. 用于更新和初始化
        obj = model.tb.objects.get(id=1)
        model_form_obj = XXOOModelForm(request.POST,instance=obj)
        ...
 
        PS: 单纯初始化
            model_form_obj = XXOOModelForm(initial={...})

ModelForm所有组件

(1)自定义插件widgets

代码语言:javascript
复制
from django.forms import widgets as Fwidgets    #避免跟widgets重名
class UserInfoModelForm(forms.ModelForm):
    class Meta:
        model = models.UserInfo     #去UserInfo类中获取数据
        fields = '__all__'        #__all__ 代指所有字段
        labels ={'username':'用户名'}
        help_texts = {'username':'...'}
        widgets = {
            'username':Fwidgets.Textarea(attrs={'class':'c1'})
        }

(2)错误信息error_message

代码语言:javascript
复制
from django.forms import widgets as Fwidgets    #避免跟widgets重名
class UserInfoModelForm(forms.ModelForm):
    class Meta:
        ---snip---
        error_messages = {
            '__all__':{},       #整体的错误信息
            'email':{'required':'邮箱不能为空'}
        }

(3)自定义更改字段验证规则field_classses

代码语言:javascript
复制
from django.forms import fields as Ffields     #避免跟fields重名
class UserInfoModelForm(forms.ModelForm):
    class Meta:
        ---snip---
        field_classes ={
            'email':Ffields.URLField    #把邮件格式改为url格式验证
        }
代码语言:javascript
复制
from django.shortcuts import render,redirect
from app01 import models
from django import forms
from django.forms import fields
from django.forms import widgets as Fwidgets
from django.forms import fields as Ffields     


class UserInfoModelForm(forms.ModelForm):
    class Meta:
        model = models.UserInfo  # 去UserInfo类中获取数据
        fields = '__all__'  # __all__ 代指所有字段
        labels = {'username': '用户名'}
        help_texts = {'username': '...'}
        widgets = {
            'username': Fwidgets.Textarea(attrs={'class': 'c1'})
        }
        error_messages = {
            '__all__': {},  # 整体的错误信息
            'email': {'required': '邮箱不能为空'}
        }
        field_classes = {
            'email': Ffields.URLField  # 把邮件格式改为url格式验证
        }

def index(request):
    if request.method == 'GET':
        obj = UserInfoModelForm()
        return render(request,'index.html',{'obj':obj})
    elif request.method == 'POST':
        obj = UserInfoModelForm(request.POST)
        result = obj.is_valid()
        if result:
            print(obj.cleaned_data)             #如果models里没有__str__方法,则user_type获取
                                                        #到的是一个对象,可直接根据对象进行操作
            print(obj.cleaned_data['user_type'])
            # {'username': 'James', 'user_type': < UserType: 超级用户 >, 'email': 'ffd@fdsf.com'}
            # 超级用户
        else:
            print(obj.errors)
        return render(request,'index.html',{'obj':obj})

3.ModelForm创建保存数据

代码语言:javascript
复制
from django.db import models

# Create your models here.

class UserInfo(models.Model):
    # verbose_name 等同于Form类里面的label
    username = models.CharField(verbose_name='用户',max_length=32)
    email = models.EmailField(verbose_name='邮件')
    user_type = models.ForeignKey(verbose_name='类型',to='UserType',to_field='id')
    user_group = models.ManyToManyField('UserGroup')

class UserType(models.Model):
    caption = models.CharField(max_length=32)

    def __str__(self):          #打印名称,不写显示的是obj对象
        return self.caption

class UserGroup(models.Model):
    groupname = models.CharField(max_length=32)

    def __str__(self):          #打印名称,不写显示的是obj对象
        return self.groupname
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/index/" method="post">
        {% csrf_token %}
        {{ obj.as_p }}
        <input type="submit" value="提交"/>
    </form>

</body>
</html>
代码语言:javascript
复制
from django import forms
from app import models
from django.forms import widgets as Fwidgets    #避免跟widgets重名
from django.forms import fields as Ffields     #避免跟fields重名
class UserInfoModelForm(forms.ModelForm):
    class Meta:
        model = models.UserInfo     #去UserInfo类中获取数据
        fields = '__all__'        #__all__ 代指所有字段
        labels ={'username':'用户名'}
        help_texts = {'username':'...'}
        widgets = {
            'username':Fwidgets.Textarea(attrs={'class':'c1'})
        }
        error_messages = {
            '__all__':{},       #整体的错误信息
            'email':{'required':'邮箱不能为空'}
        }

ModelForm验证

处理文件

代码语言:javascript
复制
from django.shortcuts import render
def index(request):
    if request.method == 'GET':
        obj = UserInfoModelForm()
        return render(request,'index.html',{'obj':obj})
    elif request.method == 'POST':
        obj = UserInfoModelForm(request.POST)
        if obj.is_valid():
            # 验证成功直接保存
            obj.save()         #默认commit=True,会保存多对多
            # 保存一对多表单
            # instance = obj.save(commit=False)
            # instance.save()
            # 保存多对多数据
            # obj.save_m2m()
        return render(request,'index.html',{'obj':obj})

4.ModelForm更新和初始化

描述:打开用户列表,显示用户信息,点击编辑跳转到编辑页面,Input显示选择用户的当前值;提交后,对数据进行更新

代码语言:javascript
复制
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/$', views.index),
    url(r'^list/$', views.user_list),
    url(r'^edit-(\d+)', views.user_edit),
]
代码语言:javascript
复制
from django.db import models


class UserInfo(models.Model):
    # verbose_name 等同于Form类里面的label
    username = models.CharField(verbose_name='用户',max_length=32)
    email = models.EmailField(verbose_name='邮件')
    user_type = models.ForeignKey(verbose_name='类型',to='UserType',to_field='id')
    user_group = models.ManyToManyField('UserGroup')

class UserType(models.Model):
    caption = models.CharField(max_length=32)

    def __str__(self):          #打印名称,不写显示的是obj对象
        return self.caption

class UserGroup(models.Model):
    groupname = models.CharField(max_length=32)

    def __str__(self):          #打印名称,不写显示的是obj对象
        return self.groupname

user_list.html

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for row in list %}
            <p>{{ row.username }}--{{ row.user_type.caption }}--<a href="/edit-{{ row.id }}">编辑</a></p>
        {% endfor %}
    </ul>
</body>
</html>

user_edit.html

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/edit-{{ nid }}" method="post">
        {% csrf_token %}
        {{ obj.as_p }}
        <input type="submit" value="提交" />
    </form>

</body>
</html>

views.py

代码语言:javascript
复制
from django.shortcuts import render,redirect
from app01 import models
from django import forms
from django.forms import fields
from django.forms import widgets as Fwidgets
from django.forms import fields as Ffields


class UserInfoModelForm(forms.ModelForm):
    class Meta:
        model = models.UserInfo  # 去UserInfo类中获取数据
        fields = '__all__'  # __all__ 代指所有字段
        labels = {'username': '用户名'}
        help_texts = {'username': '...'}
        widgets = {
            'username': Fwidgets.Textarea(attrs={'class': 'c1'})
        }
        error_messages = {
            '__all__': {},  # 整体的错误信息
            'email': {'required': '邮箱不能为空'}
        }

def index(request):
    if request.method == 'GET':
        obj = UserInfoModelForm()
        return render(request,'index.html',{'obj':obj})
    elif request.method == 'POST':
        obj = UserInfoModelForm(request.POST)
        if obj.is_valid():
            # 验证成功直接保存
            obj.save()         #默认commit=True,会保存多对多
            # 保存一对多表单
            # instance = obj.save(commit=False)
            # instance.save()
            # 保存多对多数据
            # obj.save_m2m()
        return render(request,'index.html',{'obj':obj})


def user_list(request):
    if request.method == 'GET':
        list = models.UserInfo.objects.all().select_related('user_type')
        return render(request, 'user_list.html', {'list': list})


def user_edit(request, nid):
    if request.method == 'GET':
        user_obj = models.UserInfo.objects.filter(id=nid).first()
        obj = UserInfoModelForm(instance=user_obj)  # instance显示user_obj的对应值
        return render(request, 'user_edit.html', {'obj': obj, 'nid': nid})
    elif request.method == 'POST':
        user_obj = models.UserInfo.objects.filter(id=nid).first()
        obj = UserInfoModelForm(request.POST, instance=user_obj)  # instance更新user_obj而不是添加
        if obj.is_valid():
            # 验证成功直接更新
            obj.save()
        else:
            print(obj.errors.as_json())
        return render(request, 'user_edit.html', {'obj': obj, 'nid': nid})
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-02-13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ModelForm
    •  1.ModeForm简单验证
      •  2.ModelForm组件
        • 3.ModelForm创建保存数据
          • 4.ModelForm更新和初始化
          相关产品与服务
          数据库
          云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档