47-django之ModelForm

ModelForm功能

ModelForm 自动生成表单+ 用户提交的语法检测

示例

app01/models.py

from django.db import models


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

    def __str__(self):
        return self.caption


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

    def __str__(self):
        return self.title

    
class UserInfo(models.Model):
    name = models.CharField(max_length=32,verbose_name='用户名')
    pwd =  models.CharField(max_length=32,verbose_name='密码')
    email = models.CharField(max_length=32,verbose_name='邮箱')

    ut = models.ForeignKey(to="UserType",blank=True,null=True,verbose_name='用户类型')

    roles = models.ManyToManyField(to="Role",blank=True,verbose_name='用户角色')

    def __str__(self):
        return self.name

app01/views.py

from django.shortcuts import render,redirect
from django.forms import ModelForm
from . import models


# ModelForm是数据库Model 和 表单Form的结合体,二者的功能都有
class TestModelForm(ModelForm):
    class Meta:  # 格式规定,必须定义Meta类
        # model = models.UserInfo
        model = models.UserType  # ModelForm应用于其他类,直接修改这个即可2(1)
        fields = "__all__"


# 根据ModelForm创建数据
def test(request):
    if request.method == "GET":
        obj = TestModelForm()
        return render(request,'test.html',{'obj':obj})  # 根据obj对象在前端根据数据库中的列和类型(FK\M2M)生成表单
    else:
        obj = TestModelForm(data=request.POST)  # 验证表单数据
        if obj.is_valid():  # 表单数据验证通过
            obj.save()  # save方法会直接将数据插入到数据库中
            return redirect('/arya/app01/userinfo/')
        return render(request, 'test.html', {'obj': obj})


# 根据ModelForm修改数据
def edit(request,nid):
    # user_obj = models.UserInfo.objects.filter(id=nid).first()
    user_obj = models.UserType.objects.filter(id=nid).first()
    # ModelForm应用于其他类,直接修改这个即可2(2if request.method == "GET":
        # 这块应该获取和user_obj相关的所有数据,并展示在表单中,不用去查询,简单的方式如下:
        obj = TestModelForm(instance=user_obj)  # 传入instance参数即初始化和这个对象相关的表单数据
        return render(request, 'edit.html', {'obj': obj})
    else:
        obj = TestModelForm(instance=user_obj,data=request.POST)
        # 使用instance + data 这种方式是更新原有记录,如果不使用这个,直接使用if分支中的obj修改后提交则是新建
        if obj.is_valid():  # 表单数据验证通过
            obj.save()  # save方法会request.POST中的数据直接更新到到数据库instance=user_obj的记录中
            return redirect('/arya/app01/userinfo/')
        return render(request, 'edit.html', {'obj': obj})

可以为ModelForm定制样式

from django.shortcuts import render,redirect

# Create your views here.
from django.forms import ModelForm
from django.forms import widgets as form_widgets
from . import models
class TestModelForm(ModelForm):
    class Meta:
        model = models.UserInfo
        # model = models.UserType
        fields = "__all__"
        # widgets = {
        #     'title':form_widgets.Input(attrs={'class':'c1'})
        #     'title':form_widgets.Textarea(attrs={'class':'c1'})
        # }
        # error_messages = {
        #     'title':{
        #         'required':'标题不能为空'
        #     }
        # }

关于Meta信息还可以这么使用

class UserInfoModelForm(ModelForm):
    class Meta:
        model = models.UserInfo
        fields = "__all__"         # 包含所有字段
        # fields = ['name','pwd']  # 仅包含哪些字段
        # exclude = ['name']       # 排除哪些字段
        error_messages = {         # 错误信息是什么
            'name':{
                'required':'用户名不能为空',
            },
            'pwd': {
                'required': '密码不能为空',
            }
        }

全局urls.py

from django.conf.urls import url,include
from django.contrib import adminfrom app01 import views

urlpatterns = [
    ....
    url(r'^test/', views.test),  # arya:name
    url(r'^edit/(\d+)/', views.edit),  # arya:name
]

templates/test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>添加页面</h1>
<form method="POST" novalidate>
    {% csrf_token %}
    {{ obj.as_p }}  <!--通过obj.as_p 自动生成form表单,也可以自己手工生成form表单-->
    <input type="submit" value="提交">
</form>

</body>
</html>

templates/edit.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>编辑页面</h1>
<form method="POST" novalidate>
    {% csrf_token %}
    {{ obj.as_p }}
    <input type="submit" value="提交">
</form>

</body>
</html>

关于as_p,

                    <!-- 还可以通过{{ item.label }} {{ item }} {{ item.errors.0 }}  这种方式自主显示哪些列-->

或者如下循环的方式来自主显示和控制样式

<form class="form-horizontal" method="POST" novalidate>

        {% csrf_token %}

        {% for item in form %}
            <div class="form-group col-sm-6" style="margin-bottom: 20px;">
                <label for="inputEmail3" class="col-sm-2 control-label">{{ item.label }}</label>
                <div class="col-sm-10" style="position: relative">
                    <!-- <input type="email" class="form-control" id="inputEmail3" placeholder="Email"> -->
                    {{ item }}
                    <div style="position: absolute;">{{ item.errors.0 }}</div>
                </div>

            </div>
        {% endfor %}


        <div class="form-group">
            <div class="col-sm-offset-1 col-sm-10">
                <input type="submit" class="btn btn-primary" value="提交">
            </div>
        </div>
    </form>

 

posted @ 2017-11-26 23:48  番茄土豆西红柿  阅读(82)  评论(0)    收藏  举报
TOP