返回顶部
扩大
缩小

Zhang_derek

10.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
model.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
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
models
复制代码
复制代码
<!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
复制代码
复制代码
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验证
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),
]
url.py
复制代码
复制代码
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
model.py
复制代码

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})
复制代码

 

posted on   zhang_derek  阅读(736)  评论(0编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示

目录导航