Django+MySQL学生表提交报错:prn_no字段期望数字却得到元组
问题:Django表单提交时报错Field 'prn_no' expected a number but got ('1',)
我基于Django框架和MySQL数据库搭建了「校园管理系统(School Management System)」,系统包含5张数据表,其余表均可正常读写,但Student和Faculty表提交时出现如下错误:
TypeError at /studentform Field 'prn_no' expected a number but got ('1',)
我已尝试删除所有Django迁移文件并重新执行python manage.py makemigrations和python manage.py migrate操作,问题仍未解决。以下是相关代码片段及完整错误回溯信息:
studentform.html
{% extends 'base.html' %} {% block title %}Student{% endblock title %} {% block body %} <div class="container"> <br> <form class="row g-3" method="post" action="/studentform"> {% csrf_token %} <div class="col-md-4"> <label for="prn_no" class="form-label">prn_no</label> <input type="number" class="form-control" id="prn_no" name="prn_no" required> </div> <div class="col-md-4"> <label for="fname" class="form-label">fname</label> <input type="text" class="form-control" id="fname" name="fname" required> </div> <div class="col-md-4"> <label for="lname" class="form-label">lname</label> <input type="text" class="form-control" id="lname" name="lname" required> </div> <div class="col-md-4"> <label for="DOB" class="form-label">DOB</label> <input type="date" class="form-control" id="DOB" name="DOB" required> </div> <div class="col-md-4"> <label for="Address" class="form-label">Address</label> <input type="text" class="form-control" id="Address" name="Address" required> </div> <div class="col-md-3"> <label for="gender" class="form-label">gender</label> <select class="form-select" id="gender" name="gender" required> <option selected disabled value="">Choose...</option> <option>M</option> <option>F</option> <option>O</option> </select> </div> <div class="col-md-4"> <label for="Standard" class="form-label">Standard</label> <input type="text" class="form-control" id="Standard" name="Standard" required> </div> <div class="col-md-6"> <label for="guardian_id" class="form-label">guardian_id</label> <input type="text" class="form-control" id="guardian_id" name="guardian_id" required> </div> <br> <div class="col-12"> <button class="btn btn-primary" type="submit" >Submit Data</button> </div> </form> </div> {% endblock body %}
views.py
def studentform(request): if request.method == "POST": prn_no = request.POST.get('prn_no'), fname = request.POST.get('fname'), lname = request.POST.get('lname'), dob = request.POST.get('dob'), address = request.POST.get('address'), gender = request.POST.get('gender'), standard = request.POST.get('standard'), guardian_id = request.POST.get('guardian_id') s1 = student1(prn_no = prn_no , fname = fname , lname = lname, dob = dob , address = address , gender = gender, standard = standard , guardian_id = guardian_id ) s1.save() return render(request,'studentform.html')
models.py
class student1(models.Model): prn_no = models.IntegerField() fname = models.CharField(max_length=20) lname = models.CharField(max_length=20) dob = models.DateField() address = models.CharField(max_length=20) gender = models.CharField(max_length=20) standard = models.CharField(max_length=20) guardian_id = models.CharField(max_length=20) class Meta: app_label = 'page1' db_table='student'
错误回溯信息
Environment: Request Method: POST Request URL: http://127.0.0.1:8000/studentform Django Version: 4.0 Python Version: 3.11.0 Installed Applications: ['page1.apps.Page1Config', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles'] Installed Middleware: ['django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware'] Traceback (most recent call last): File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\db\models\fields\__init__.py", line 1822, in get_prep_value return int(value) The above exception (int() argument must be a string, a bytes-like object or a real number, not 'tuple') was the direct cause of the following exception: File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\core\handlers\exception.py", line 47, in inner response = get_response(request) File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\core\handlers\base.py", line 181, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "C:\Users\Aakash\Desktop\Mini Project\sms\page1\views.py", line 86, in studentform s1.save() File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\db\models\base.py", line 743, in save self.save_base(using=using, force_insert=force_insert, File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\db\models\base.py", line 780, in save_base updated = self._save_table( File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\db\models\base.py", line 885, in _save_table results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw) File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\db\models\base.py", line 923, in _do_insert return manager._insert( File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\db\models\manager.py", line 85, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\db\models\query.py", line 1301, in _insert return query.get_compiler(using=using).execute_sql(returning_fields) File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\db\models\sql\compiler.py", line 1440, in execute_sql for sql, params in self.as_sql(): File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\db\models\sql\compiler.py", line 1382, in as_sql value_rows = [ File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\db\models\sql\compiler.py", line 1383, in <listcomp> [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields] File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\db\models\sql\compiler.py", line 1383, in <listcomp> [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields] File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\db\models\sql\compiler.py", line 1324, in prepare_value value = field.get_db_prep_save(value, connection=self.connection) File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\db\models\fields\__init__.py", line 839, in get_db_prep_save return self.get_db_prep_value(value, connection=connection, prepared=False) File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\db\models\fields\__init__.py", line 834, in get_db_prep_value value = self.get_prep_value(value) File "C:\Users\Aakash\anaconda3\envs\Django\Lib\site-packages\django\db\models\fields\__init__.py", line 1824, in get_prep_value raise e.__class__( Exception Type: TypeError at /studentform Exception Value: Field 'prn_no' expected a number but got ('1',).
问题原因及解决方法
核心问题1:变量后多余的逗号导致生成元组
在views.py中,多个变量赋值后加了逗号,比如:
prn_no = request.POST.get('prn_no'), fname = request.POST.get('fname'),
Python中,单个值加逗号会被解析为元组,比如prn_no实际是('1',)而不是字符串'1'。而models.py中prn_no定义为IntegerField,需要传入数字类型,元组无法被转换为整数,因此触发报错。
核心问题2:表单字段名与视图获取名不匹配
表单中日期字段的name是DOB(大写),但视图中用request.POST.get('dob')(小写),会导致dob值为None,保存时会触发DateField不能为空的错误;同理Address和address、Standard和standard也存在大小写不匹配的问题。
修改后的views.py代码
def studentform(request): if request.method == "POST": # 去掉变量后的逗号,同时修正字段名大小写匹配 prn_no = int(request.POST.get('prn_no')) # 转成整数匹配IntegerField fname = request.POST.get('fname') lname = request.POST.get('lname') dob = request.POST.get('DOB') address = request.POST.get('Address') gender = request.POST.get('gender') standard = request.POST.get('Standard') guardian_id = request.POST.get('guardian_id') s1 = student1( prn_no=prn_no, fname=fname, lname=lname, dob=dob, address=address, gender=gender, standard=standard, guardian_id=guardian_id ) s1.save() return render(request,'studentform.html')
额外建议
推荐使用Django的ModelForm来处理表单,它会自动映射模型字段,避免手动处理字段名和类型转换的问题,代码更简洁且不易出错。示例:
# forms.py from django import forms from .models import student1 class StudentForm(forms.ModelForm): class Meta: model = student1 fields = '__all__' # 或指定需要的字段 # views.py def studentform(request): if request.method == "POST": form = StudentForm(request.POST) if form.is_valid(): form.save() else: form = StudentForm() return render(request,'studentform.html', {'form': form})
模板中可以直接使用{{ form.as_p }}或手动渲染字段,无需手动编写所有input标签。
内容的提问来源于stack exchange,提问作者Aakash Rohila
相关产品推荐
相关产品推荐

