Django006:ModelForm组件

2023-10-14 11:12:55 浏览数 (2)

传统方法的痛点

  1. 用户提交数据没有校验。
  2. 页面上,每一个字段都需我们重写一遍。
  3. 关联的数据,手动去获取并展示循环展示再页面。

基于以上的痛点,我们在使用Django开发的时候就可以引用ModelForm组件,他是Django中特有的,并在传统的开发的步骤的基础上,优化了以上总结的痛点。

ModelForm组件

前提(models.py)

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


class BMB(models.Model):
    """ 部门表 """
    title = models.CharField(verbose_name='部门', max_length=32)

    def __str__(self):
        return self.title

class YGB(models.Model):
    """ 员工表 """
    name = models.CharField(verbose_name="姓名", max_length=16)
    password = models.CharField(verbose_name="密码", max_length=64)
    age = models.IntegerField(verbose_name="年龄")
    account = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
    create_time = models.DateField(verbose_name="入职时间")
    depart = models.ForeignKey(verbose_name="部门",to="BMB", to_field="id", on_delete=models.CASCADE)
models.ForeignKey(to="BMB",to_fields="id",null=True,blank=True,on_delete=models.SET_NULL)

    gender_choices = (
        (1, "男"),
        (2, "女")
    )
    gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)

信息校验

views.py

其中:name = forms.CharField(min_length=3, label="用户名") 说明:通过上面的name再在自动校验name字段是否由内容的同时同时校验name字段输入最小的字段不小3个字符。

if form.is_valid():         # 如果数据合法保存到数据库         form.save()  说明:如果校验成功,通过form.save()直接保存到数据库(比传统的存入方式简便,增加了代码的可读性。)

代码语言:javascript复制
from django import forms


class UserModelForm(forms.ModelForm):
    name = forms.CharField(min_length=3, label="用户名")

    class Meta:
        model = models.YGB
        fields = ['name', 'password', 'age', 'account', 'create_time', 'gender', 'depart']


def user_model_form_add(request):
    """添加用户(ModelForm组件版本"""
    if request.method == "GET":
        form = UserModelForm()
        return render(request, 'user_model_form_add.html', {'form': form})
    # 用户post提交数据,数据校验
    form = UserModelForm(data=request.POST)
    if form.is_valid():
        # 如果数据合法保存到数据库
        form.save()
        return redirect('/user/list/')
    else:
        return render(request, 'user_model_form_add.html', {"form": form})
user_model_form_add.html
代码语言:javascript复制
{% extends 'layout.html' %}

{% block content %}
    <form method="post" novalidate>
    {% csrf_token %}
        {% for obj in form %}
            <div style="display: flex;flex-direction: column;width: 500px">
                {{ obj.label }}:{{ obj }}
            </div>
            <span style="color: red">{{ obj.errors.0 }}</span>
        {% endfor %}
    <button type="submit">立即创建</button>
    </form>
{% endblock %}

将自动校验设为中文

setting.py
代码语言:javascript复制
LANGUAGE_CODE = 'zh-hans'

添加信息页面校验信息提示

前端复写

views.py
代码语言:javascript复制
from django import forms


class UserModelForm(forms.ModelForm):
    name = forms.CharField(min_length=3, label="用户名")

    class Meta:
        model = models.YGB
        fields = ['name', 'password', 'age', 'account', 'create_time', 'gender', 'depart']


def user_model_form_add(request):
    """添加用户(ModelForm组件版本"""
    if request.method == "GET":
        form = UserModelForm()
        return render(request, 'user_model_form_add.html', {'form': form})
    # 用户post提交数据,数据校验
    form = UserModelForm(data=request.POST)
    if form.is_valid():
        # 如果数据合法保存到数据库
        form.save()
        return redirect('/user/list/')
    else:
        return render(request, 'user_model_form_add.html', {"form": form})
user_model_form_add.html

通过以下方法将views.py中的form接收并循环到前端html(复写了html的同时代替原本传统的前端html的编写)         {% for obj in form %}             <div style="display: flex;flex-direction: column;width: 500px">                 {{ obj.label }}:{{ obj }}             </div>             <span style="color: red">{{ obj.errors.0 }}</span>         {% endfor %} 注意:此方法只是用Django框架,所以若用Django写全栈的话是非常不错的选择。            但是,若想前后端分离,只想让Django写后端的话,此方法不是最佳选择。

代码语言:javascript复制
{% extends 'layout.html' %}

{% block content %}
    <form method="post" novalidate>
    {% csrf_token %}
        {% for obj in form %}
            <div style="display: flex;flex-direction: column;width: 500px">
                {{ obj.label }}:{{ obj }}
            </div>
            <span style="color: red">{{ obj.errors.0 }}</span>
        {% endfor %}
    <button type="submit">立即创建</button>
    </form>
{% endblock %}

关联数据(编辑页面为例)

通过以下方法快速关联数据库中的每一行的数据:

代码语言:javascript复制
row_obj = models.YGB.objects.filter(id=nid).first()
form = UserModelForm(data=request.POST, instance=row_obj)

instance=row_obj与filter(id=nid)说明:用传递的nid参数做标识,用instance指定此标识所在的数据行。

代码语言:javascript复制
from django import forms


class UserModelForm(forms.ModelForm):
    name = forms.CharField(min_length=3, label="用户名")

    class Meta:
        model = models.YGB
        fields = ['name', 'password', 'age', 'account', 'create_time', 'gender', 'depart']
def user_edit(request, nid):
    """编辑用户"""
    row_obj = models.YGB.objects.filter(id=nid).first()
    if request.method == 'GET':
        form = UserModelForm(instance=row_obj)
        return render(request, 'user_edit.html', {'form': form})

    form = UserModelForm(data=request.POST, instance=row_obj)
    if form.is_valid():
        # 如果数据合法保存到数据,如果想要保存不需要用户输入的默认值
        # form.instance.<字段名> = 值
        form.save()
        return redirect('/user/list/')
    else:
        return render(request, 'user_edit.html', {"form": form})
user_edit.html
代码语言:javascript复制
{% extends 'layout.html' %}

{% block content %}
    <form method="post" novalidate>
    {% csrf_token %}
        {% for obj in form %}
            {{ obj.label }}:{{ obj }}
            <span style="color: red">{{ obj.errors.0 }}</span>
        {% endfor %}
    <button type="submit">修改信息</button>
    </form>
{% endblock %}
编辑页面效果

0 人点赞