django自定义表单

文章目录

django自定义表单

两种方式

  1. 继承Form
  2. 继承ModelForm
python 复制代码
from django import forms
from .models import Contact

# 自定义表单字段
class ContactForm1(forms.Form):
    name = forms.CharField(label="Your Name", max_length=255)
    email = forms.EmailField(label="Email address")

# 根据模型创建
class ContactForm2(forms.ModelForm):
    
    class Meta:
        model = Contact   #指定表单与哪个Django模型相关联
        fields = ('name', 'email',)  #指定表单应该包含的模型字段

自定义错误信息

python 复制代码
from django import forms

class LoginForm(forms.Form):  
    username = forms.CharField(
        required=True,
        max_length=20,
        min_length=6,
        error_messages={
            'required': '用户名不能为空',
            'max_length': '用户名长度不得超过20个字符',
            'min_length': '用户名长度不得少于6个字符',
        }
    )
    password = forms.CharField(
        required=True,
        max_length=20,
        min_length=6,
        error_messages={
            'required': '密码不能为空',
            'max_length': '密码长度不得超过20个字符',
            'min_length': '密码长度不得少于6个字符',
        }
    )

widgets

widgets 是表单和模型表单的一个属性,它允许你指定每个表单字段的HTML控件类型,以及它们的大小、样式等细节。

python 复制代码
from django import forms
from myapp.models import Author

class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = ('name', 'title', 'birth_date')
        widgets = {
            'name': forms.TextInput(attrs={'cols': 80}),  # 使用 TextInput 并设置合适的宽度
            'title': forms.TextInput(attrs={'cols': 50}),  # 假设 title 也是单行文本
            'birth_date': forms.DateInput(attrs={'type': 'date'}),  # 使用 DateInput 来输入日期
        }
        labels = {
            'name': 'Author Name',  # 更具体的标签
            'title': 'Title',  # 为 title 字段设置标签
            'birth_date': 'Birth Date',  # 为 birth_date 字段设置标签
        }
        help_texts = {
            'name': 'Enter the author\'s full name.',  # 提供更具体的帮助文本
            'title': 'Enter the author\'s title, if any.',  # 提供 title 字段的帮助文本
            'birth_date': 'Enter the author\'s birth date.',  # 提供 birth_date 字段的帮助文本
        }
        error_messages = {
            'name': {
                'max_length': "The author's name is too long.",  # 自定义错误消息
            },
            'title': {
                'max_length': "The title is too long.",  # 如果 title 字段有最大长度限制,添加自定义错误消息
            },
            'birth_date': {
                'invalid': "Enter a valid birth date.",  # 添加日期无效的错误消息
            },
        }

实例化和初始化

在定义完表单类后,要对其进行实例化和初始化。

python 复制代码
form = ContactForm()  #空表单

需要给表单设置初始数据,通过initial方法或设置default_data:

python 复制代码
# initial方法初始化
form = ContactForm(
    initial={
        'name': 'First and Last Name',
    },)

# default_data默认值
default_data = {'name': 'John', 'email': 'someone@hotmail.com', }
form = ContactForm(default_data)

处理用户提交的数据

python 复制代码
form = ContactForm(data=request.POST)

表示将使用请求对象 request 中的 POST 字典来填充表单

##给表单提供现有实例对象

在编辑或修改现有对象的场景中,可以使用Django的ModelForm来提供现有对象的数据,而不是渲染一个空表单。

python 复制代码
contact = get_object_or_404(Contact, pk=id)  # 获取模型实例
form =  ContactForm(instance = contact, data=request.POST)  # 指定一个已经存在于数据库中的模型实例。当创建表单时,Django 会使用这个实例的当前数据来预填充表单字段。这样,当用户编辑一个对象并提交表单时,表单会显示该对象的当前值,而不是空字段。 

显示一个指定的现有对象的值,用户提交表单后使用请求对象的POST来填充表单。

该方法仅适用于由模型创建的ModelForm,而不适用于自定义的表单。

验证表单

每个forms类可以通过clean方法自定义表单验证。

python 复制代码
def clean_username(self):
        username = self.cleaned_data.get('username')

        if len(username) < 6:
            raise forms.ValidationError("Your username must be at least 6 characters long.")
        elif len(username) > 50:
            raise forms.ValidationError("Your username is too long.")
        else:
            user = User.objects.filter(username__exact=username).first()
            if user.exists():
                raise forms.ValidationError("Your username already exists.")

通用类试图使用表单

python 复制代码
使用form_class
class View(FormView):
    model = Article
    form_class = ContactForm
    template_name = ''

Formset

Formset 是一个用于处理一组表单的特殊对象。当你需要在单个页面上显示和处理多个相同类型的表单时,也就是处理表单中的表单时,Formset 非常有用。

而Formset的使用分为四步:

  1. 定义表单类
  2. 创建表单类
  3. 视图中实用表单集
  4. 在模板中渲染表单集

举个例子:

一个在线商店,商店允许顾客创建多个订单,每个订单包含多个商品。可以使用Django的Formset来管理顾客添加到购物车的多个商品。

  1. 定义一个表单来收集顾客对每个商品的选择数量
python 复制代码
from django import forms

class ProductForm(forms.Form):
    quantity = forms.IntegerField(min_value=1, max_value=10, required=False, label='Quantity')
  1. 创建一个Formset来管理顾客添加到购物车的所有商品表单
python 复制代码
from django.forms import formset_factory

ProductFormSet = formset_factory(ProductForm, extra=0, can_delete=True) 
# extra=0表示初始时不显示额外的商品表单,顾客需要从商品列表中选择。
# can_delete=True允许顾客删除他们不再想要的商品。
  1. 视图函数中,你处理顾客的POST请求,创建Formset实例,并保存顾客选择的商品
python 复制代码
 formset = ProductFormSet(request.POST)
  1. 模板中,你需要渲染Formset并显示商品列表供顾客选择
python 复制代码
<form method="post">
    {% csrf_token %}
    {{ formset.management_form }}
    {% for form in formset %}
        {{ form.as_p }}
        <!-- 显示商品列表和顾客的选择 -->
        <select name="{{ form.product.name }}" id="{{ form.product.id }}">
            <option value="1">1</option>
            <option value="2">2</option>
            <!-- ...更多商品选项 -->
        </select>
    {% endfor %}
    <input type="submit" value="Add to Cart">
</form>

本人也处于学习阶段,若有错误与不足请指出,关注DPT一起进步吧。

相关推荐
Tttian6224 小时前
Vue全栈开发旅游网项目(11)-用户管理前端接口联调
前端·vue.js·django
工业互联网专业6 小时前
Python毕业设计选题:基于Django+uniapp的公司订餐系统小程序
vue.js·python·小程序·django·uni-app·源码·课程设计
知识的宝藏12 小时前
如何使用Django写个接口,然后postman中调用
django·postman
Mr.咕咕15 小时前
Django 搭建数据管理web——商品管理
前端·python·django
pcj_88816 小时前
Django基础用法+Demo演示
python·django
工业互联网专业16 小时前
Python毕业设计选题:基于django+vue的仓库管理系统设计
vue.js·python·django·毕业设计·源码·课程设计
q567315232 天前
通过scrapy和Django登录、爬取和持久化数据
java·开发语言·数据库·scrapy·django
喝旺仔la2 天前
异步提交Django
后端·python·django
计算机学姐2 天前
基于Python的高校成绩分析管理系统
开发语言·vue.js·后端·python·mysql·pycharm·django
计算机学姐2 天前
基于Python的药房管理系统
开发语言·vue.js·后端·python·mysql·pycharm·django