专栏首页有趣的django33.Django ModelForm

33.Django ModelForm

ModelForm

 1.ModeForm简单验证

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
<!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

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组件

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

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

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

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

from django.forms import fields as Ffields     #避免跟fields重名
class UserInfoModelForm(forms.ModelForm):
    class Meta:
        ---snip---
        field_classes ={
            'email':Ffields.URLField    #把邮件格式改为url格式验证
        }
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创建保存数据

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
<!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>
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验证

处理文件

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显示选择用户的当前值;提交后,对数据进行更新

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),
]
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

<!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

<!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

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})

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 32.Django form组件

    Form组件  Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面...

    zhang_derek
  • Django+xadmin打造在线教育平台(三)

    代码 github下载 五、用户注册 主要实现功能 用户输入邮箱、密码和验证码,点注册按钮 如果输入的不正确,提示错误信息 如果正确,发送激活邮件,用户...

    zhang_derek
  • CRM客户关系管理系统(九) 第九章、filter_horizontal优化和kingadmin删除功能

    zhang_derek
  • python【第二十篇】Django表的多对多、Ajax

    这种方式无法直接操作第三张表,但是可以通过10行r这个对象,进行间接操作第三张表:

    用户1432189
  • django request.META 获取用户真实地址

    kirin
  • 如何使用jMeter对需要CSRF token验证的OData服务进行并发性能测试

    In my previous blog JMeter beginner – how to use JMeter to measure performance o...

    Jerry Wang
  • Sublime 部分问题解决

    将控制台界面(console)调出(在view选项中),使用如下命令安装包控制器。

    用户2657851
  • Github 项目推荐 | 最小化类 AlphaGo Zero 引擎 —— Nochi

    Nochi 是一个极简的 AlphaGo 引擎,它用 Keras 神经模型代替 Monte Carlo 模拟。Nochi 不会像 Michi 那样受人瞩目,但是...

    AI研习社
  • 测试数据科学家聚类技术的40个问题(能力测验和答案)(下)

    【AI100 导读】本次测试的重点主要集中在概念、聚类基本原理以及各种技术的实践知识等方面。本文为下部,包括21-40题。上部请查看: 测试数据科学家聚类技术的...

    AI科技大本营
  • R语言日常笔记(2)distinc函数

    从结果发现d1也就是用match的速度非常快! 而在tidyverse方法中, d3的summarize显然更好。

    用户1359560

扫码关注云+社区

领取腾讯云代金券