记录一次关于表单与模型进行数据交互的自学内容。
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),路由略。
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