【Youtobe trydjango】Django2.2教程和React实战系列九【Django模型表单、HTML原生表单、纯Django表单、表单验证方法和初始化方法】

1. Django模型表单

1.1. 模型表单

新建表单模型文件:src\trydjango\products\forms.py

from django import forms

from .models import Product


class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = [
            'title',
            'description',
            'price',
        ]

1.2. 视图函数

src\trydjango\products\views.py视图中新增视图函数product_create_view

from .forms import ProductForm

def product_create_view(request):
    form = ProductForm(request.POST or None)
    if form.is_valid():
        form.save()

    context = {
        'form': form,
    }
    return render(request, "products/product_create.html", context)

1.3. 前端模板

products应用中新建模板文件templates\products\product_create.html

{% extends 'base.html' %}

{% block content %}
<form>
{{ form.as_p }}
<input type='submit' value='Save' />
</form>
{% endblock %}

1.4. 路由

项目路由中urls.py新增

from products.views import product_create_view

path('create/', product_create_view),       # 创建产品

1.5. 效果

效果
在这里插入图片描述

在这里插入图片描述

products应用中的模板文件templates\products\product_create.html修改为

{% extends 'base.html' %}

{% block content %}
<form method='POST'> {% csrf_token %}
{{ form.as_p }}
<input type='submit' value='Save' />
</form>
{% endblock %}

重新提交创建请求 查看报错:
在这里插入图片描述

原因是因为模型中的必填项布尔类型字段featured没有值,给一个默认值,并进行数据库迁移操作:

在这里插入图片描述

重新测试,成功创建数据:

在这里插入图片描述

想要做出一个插入成功后,后端再返回一个空form效果,只需要在views.py增加这样一句:
form = ProductForm()
在这里插入图片描述

重启开发服务器后,插入数据后页面重新载入一个空表单。

2. HTML原生表单

2.1. 修改前端文件

templates\products\product_create.html

{% extends 'base.html' %}

{% block content %}
<form method='POST'>
    <input type='text' name='title' placeholder='Your title'>
    <input type='submit' value='Save' />
</form>
{% endblock %}

视图函数
src\trydjango\products\views.py视图中修改视图函数product_create_view

def product_create_view(request):
    context = {}
    return render(request, "products/product_create.html", context)

解决csrf
待定
在这里插入图片描述

表单方法改成GET <form method='GET'>试一下
在这里插入图片描述
表单改成<form action='/search/' method='POST'>试一下,相当于跳转到另一个url
在这里插入图片描述
将html这两行改成

<form action='https://www.bing.com/search' method='GET'> 
    <input type='text' name='q' placeholder='Your search'>

测试下
在这里插入图片描述

表单中添加csrf防中间人攻击
<form action='.' method='POST'> {% csrf_token %}
页面提交不会报403

views.py
打印请求看一下

def product_create_view(request):
    print(request.GET)
    print(request.POST)
    context = {}
    return render(request, "products/product_create.html", context)

在这里插入图片描述

在这里插入图片描述
product_create_view方法:

def product_create_view(request):
    # print(request.GET)
    # print(request.POST['title'])
    if request.method == 'POST':
        my_new_title = request.POST.get('title')
        print(my_new_title)
        # Product.objects.create(title=my_new_title)
    context = {}
    return render(request, "products/product_create.html", context)

在这里插入图片描述

3. 纯Django表单

3.1. 表单模型

forms.py

from django import forms

class RawProductForm(forms.Form):
    title       = forms.CharField()
    description = forms.CharField()
    price = forms.DecimalField()

3.2. 视图

views.py.py

from .forms import ProductForm, RawProductForm

def product_create_view(request):
    my_form = RawProductForm()
    context = {
        'form': my_form,
    }
    return render(request, "products/product_create.html", context)

3.3. 模板

form.as_ul

{% extends 'base.html' %}

{% block content %}
<form action='.' method='POST'> {% csrf_token %}
    {{ form.as_ul }}
    <input type='submit' value='Save' />
</form>
{% endblock %}

form.as_p

在这里插入图片描述

views.py
探究下Django的表单验证RawProductForm方法塞request.POST参数:

def product_create_view(request):
    my_form = RawProductForm(request.POST)
    context = {
        'form': my_form,
    }
    return render(request, "products/product_create.html", context)

会提示必填字段
在这里插入图片描述
添加表单验证:

def product_create_view(request):
    my_form = RawProductForm()
    if request.method == 'POST':
        my_form = RawProductForm(request.POST)
        if my_form.is_valid():
            # now the data is good
            print(my_form.cleaned_data)
        else:
            print(my_form.errors)
    context = {
        'form': my_form,
    }
    return render(request, "products/product_create.html", context)

在这里插入图片描述

将前端价格输入框改成text类型
在这里插入图片描述
在价格输入框填写非数字提交测试:
前端返回验证表单数据结果:
在这里插入图片描述
后端请求:
在这里插入图片描述
验证有了之后,在验证表单数据没问题后,可以使用django orm将数据保存进数据库:

Product.objects.create(my_form.cleaned_data)

在这里插入图片描述
测试一下,会报参数错误,
在这里插入图片描述
在参数前加**代表将一个可变的关键字参数的字典传给函数实参
在这里插入图片描述
此时数据已经创建成功
在这里插入图片描述

3.4. 表单属性

forms.py

class RawProductForm(forms.Form):
    title = forms.CharField(label='')
    description = forms.CharField(required=False)
    price = forms.DecimalField(initial=66.6)

在这里插入图片描述

修改下属性

class RawProductForm(forms.Form):
    title = forms.CharField(label='', widget=forms.TextInput(attrs={'placeholder': "Your title"}))
    description = forms.CharField(
        required=False,
        widget=forms.Textarea(
            attrs={
                'class': "new-class-name two",
                'id': "my-id-for-textarea",
                'rows': 20,
                'cols': 100,
            }))
    price = forms.DecimalField(initial=66.6)

在这里插入图片描述

3.5. 表单验证方法

将上面views.py的原生Django表单对应的product_create_view方法注释掉,回到最开始的Django模型表单对应的方法,解开注释:

forms.py然后将模型RawProductForm的字段复制到ProductForm中:

在这里插入图片描述
ProductForm模型添加clean_title验证标题的方法案例:

class ProductForm(forms.ModelForm):
    title = forms.CharField(label='', widget=forms.TextInput(attrs={'placeholder': "Your title"}))
    description = forms.CharField(
        required=False,
        widget=forms.Textarea(
            attrs={
                'class': "new-class-name two",
                'id': "my-id-for-textarea",
                'rows': 20,
                'cols': 100,
            }))
    price = forms.DecimalField(initial=66.6)

    class Meta:
        model = Product
        fields = [
            'title',
            'description',
            'price',
        ]
        
    def clean_title(self, *args, **kwargs):
        title = self.cleaned_data.get('title')
        if "admin" in title:
            return title
        else:
            raise forms.ValidationError("This is not a valid title")

测试结果
在这里插入图片描述
clean_title方法改成

    def clean_title(self, *args, **kwargs):
        title = self.cleaned_data.get('title')
        if not "admin" in title:
            raise forms.ValidationError("This is not a valid title")
        if not "news" in title:
            raise forms.ValidationError("This is not a valid title")
        return title

在这里插入图片描述

在这里插入图片描述

再来一个验证email字段的例子:

class ProductForm(forms.ModelForm):
    title       = forms.CharField(label='', widget=forms.TextInput(attrs={'placeholder': "Your title"}))
    email       = forms.EmailField()
    description = forms.CharField(
        required=False,
        widget=forms.Textarea(
            attrs={
                'class': "new-class-name two",
                'id': "my-id-for-textarea",
                'rows': 20,
                'cols': 100,
            }))
    price       = forms.DecimalField(initial=66.6)

    class Meta:
        model = Product
        fields = [
            'title',
            'email',
            'description',
            'price',
        ]

    def clean_title(self, *args, **kwargs):
        title = self.cleaned_data.get('title')
        if not "admin" in title:
            raise forms.ValidationError("This is not a valid title")
        if not "news" in title:
            raise forms.ValidationError("This is not a valid title")
        return title
    
    def clean_email(self, *args, **kwargs):
        email = self.cleaned_data.get('email')
        if not "edu" in email:
            raise forms.ValidationError("This is not a valid email")
        return email

在这里插入图片描述
邮箱中包含edu字符串则可以通过验证

3.6. 表单初始值

将刚才views.py中的视图函数product_create_view注释并复制一份,修改成如下:

def product_create_view(request):
    initial_data = {
        'title': 'This is a initial valid admin news title!',
    }
    # obj = Product.objects.get(id=1)
    form = RawProductForm(request.POST or None, initial=initial_data)
    
    context = {
        'form': form,
    }
    return render(request, "products/product_create.html", context)

这一个RawProductForm 纯Django 表单初始化字段值的例子:

在这里插入图片描述

def product_create_view(request):
    initial_data = {
        'title': 'This is a initial valid admin news title!',
    }
    obj = Product.objects.get(id=1)
    form = ProductForm(request.POST or None, initial=initial_data, instance=obj)
    
    context = {
        'form': form,
    }
    return render(request, "products/product_create.html", context)

在这里插入图片描述
加数据验证后保存信息

def product_create_view(request):
    initial_data = {
        'title': 'This is a initial valid admin news title!',
    }
    obj = Product.objects.get(id=1)
    form = ProductForm(request.POST or None, initial=initial_data, instance=obj)
    if form.is_valid():
        form.save()
        form = ProductForm()

    context = {
        'form': form,
    }
    return render(request, "products/product_create.html", context)

在这里插入图片描述
然后再刷新url 可以看到加载的id为1的数据被修改掉了
在这里插入图片描述
从数据库看下也是一样的:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值