django:在视图中使用表单与模型进行数据交互

导读:本篇文章讲解 django:在视图中使用表单与模型进行数据交互,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

记录一次关于表单与模型进行数据交互的自学内容。

1,项目index中的模型文件model.py:

from django.db import models

# Create your models here.
class PersonInfo(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=20)
    age = models.IntegerField()

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = '人员信息'


class Vocation(models.Model):
    id = models.AutoField(primary_key=True)
    job = models.CharField(max_length=20)
    title = models.CharField(max_length=20)
    payment = models.IntegerField(null=True, blank=True)
    person = models.ForeignKey(PersonInfo, on_delete=models.Case)

    def __str__(self):
        return str(self.id)

    class Meta:
        verbose_name = "职业信息"

前提说明:
1),使用默认的sqlite数据库。
2),一个模型对应数据库中的一张表,表与表间的三种关联关系分别由OneToOneField、ForeignKey和ManyToManyField表示。在完成数据迁移后,index_personinfo与index_vocation是一对多关系。
3),路由略。

2,向表中添加数据:
index_personinfo
index_vocation

3,项目index中的模型文件form.py:

from django import forms
from index.models import *
from django.core.exceptions import ValidationError

# 自定义验证
def payment_validate(value):
    if value > 30000:
        raise ValidationError('请输入合理薪资')


class VocationForm(forms.Form):
    use_required_attribute = False
    job = forms.CharField(max_length=20, label='职位',
                          required=False)
    title = forms.CharField(max_length=20,
                            label='职称',
                            widget=forms.widgets.TextInput(attrs={'class': 'jobtitle'}),
                            error_messages={'required': '职称不能为空!'})
    payment = forms.IntegerField(label='薪资',
                                 widget=forms.widgets.TextInput(attrs={'class': 'jobpayment',
                                                                       'placeholder': u'人民币数值(单位:元)'}),
                                 validators=[payment_validate])
    # 设置下拉选项
    value = PersonInfo.objects.values('name')
    choices = [(i + 1, v['name']) for i, v in enumerate(value)]
    person = forms.ChoiceField(choices=choices, label='姓名')

    def clean_title(self):
        data = self.cleaned_data['title']
        return '初级' + data

说明:字段参数使用了validators,就不再用error_messages了。

4,项目index中的视图文件view.py及模板index.html:

from django.shortcuts import render
from django.http import HttpResponse, HttpResponsePermanentRedirect, HttpResponseRedirect, Http404, \
    StreamingHttpResponse, FileResponse, JsonResponse
from .models import PersonInfo, Vocation
from .form import VocationForm

def index(request):
	# GET请求
    if request.method == 'GET':
        id = request.GET.get('id', '')
        # GET请求带参数时:http://127.0.0.1:8000/?id=1
        if id:
            # 根据请求参数从模型获取数据
            d = Vocation.objects.filter(id=id).values()
            d = list(d)[0]
            print("get d:", d)
            d['person'] = d['person_id']    # Vocation外键为person_id
                                            # VocationForm对应字段为person
            i = dict(initial=d, label_suffix='*', prefix='vv')
            # 将参数i传入表单VocationForm执行实例化
            v = VocationForm(**i)
        # GET请求不带参数时:http://127.0.0.1:8000
        else:
            v = VocationForm(prefix='vv')
        return render(request, 'index.html', locals())
    # POST请求
    else:
        v = VocationForm(data=request.POST, prefix='vv')
        if v.is_valid():
            # 获取网页控件name的数据
            # 方法一
            title = v['title']
            # 方法二
            # cleaned_data将控件name的数据进行清洗
            ctitle = v.cleaned_data['title']
            # 在http://127.0.0.1:8000/?id=1页面下,将数据更新到模型Vocation
            id = request.GET.get('id', '')
            d = v.cleaned_data
            d['person_id'] = int(d['person'])
            print("post d:", d)
            # 使用请求参数提交
            if id:
                Vocation.objects.filter(id=id).update(**d)
                msg = '使用请求参数提交成功'
                return HttpResponse(msg)
            # 直接修改表提交
            # 在http://127.0.0.1:8000页面下,将数据更新到模型Vocation
            else:
                # 反向查询再修改
                id = d["person"]
                query_set = PersonInfo.objects.filter(id=id).first()
                print("query_set", query_set)
                result_set = query_set.vocation_set.first()
                print("result_set", result_set)
                Vocation.objects.filter(id=id).update(**d)
                msg = '直接修改表提交成功'
                return HttpResponse(msg)
        else:
            # 获取错误信息,并以json格式输出
            error_msg = v.errors.as_json()
            print(error_msg)
            return render(request, 'index.html', locals())

<!DOCTYPE html>
<html lang="en">
<head>
    <title>title</title>
</head>
<body>
    {% if v.errors %}
        <p>
            数据出错,出错信息为:{{ v.errors }}
        </p>
    {% else %}
        <form action="" method="post">
            {% csrf_token %}
            <table>
                {{ v.as_table }}
            </table>
            <input type="submit" value="提交">
        </form>
    {% endif %}
</body>
</html>

从四种情况说明:
1),当django接受不带参数的GET请求:http://127.0.0.1:8000时,实例化表单类:v = VocationForm(prefix=‘vv’),其中prefix参数通过设置表单在html中的name和id,允许在不同网页中使用同一个表单类生成不同表单。如下图:在这里插入图片描述

2),通过请求参数获取并展示数据。
当django接受带参数的GET请求:http://127.0.0.1:8000/?id=1时,根据id参数,使用ORM API,从index_vocation表中查询相关数据: d = Vocation.objects.filter(id=id).values(),给查询结果添加VocationForm外键person数据,才能获得完整的VocationForm初始化数据,其中print(“get d:”, d)输出get d: {‘id’: 1, ‘job’: ‘喊666’, ‘title’: ‘高级程序员鼓励师’, ‘payment’: 9999, ‘person_id’: 1}。初始化时要使用prefix参数进行表单识别。如下图:
在这里插入图片描述
3),在情况2的结果页面下,可以修改除姓名以外的任何数据并完成提交。
POST请求将所有数据发送给django,然后django实例化表单类,根据接收到的内容更新数据表数据。如下图:
在这里插入图片描述
在这里插入图片描述
4),直接修改数据并完成提交。
根据下拉选项中的姓名数据,反向查询工作数据并更新,如下图
在这里插入图片描述
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/98169.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!