Django表单数据无法存入PostgreSQL数据库求助
问题描述
开发用于保存渔船押金信息的简易输入表单,Vessel(渔船)和Net(渔网)为PostgreSQL数据库中的表。提交表单时无报错,但后台无数据存入(通过PgAdmin查看),这是第一次使用Django,已尝试在表单中添加dep_id字段但无改善,请求排查原因。
相关代码
forms.py
from django import forms from django.forms import ModelForm from myapp.models import Deposit class UploadForm(ModelForm): dep_date = forms.DateField() harbour = forms.CharField() vessel = forms.ModelChoiceField(queryset=Vessel.objects.all()) net = forms.ModelChoiceField(queryset=Net.objects.all()) amount = forms.DecimalField() class Meta: model = Deposit fields = ['dep_date', 'harbour', 'vessel', 'net', 'amount']
models.py
from django.db import models class Vessel(models.Model): VID = models.IntegerField(primary_key=True, default=None) vessel_name = models.CharField(max_length=100) flag = models.CharField(max_length=100) registration_number = models.CharField(max_length=100) WIN = models.CharField(max_length=100) IRCS = models.CharField(max_length=100) vessel_type = models.CharField(max_length=250) fishing_methods = models.CharField(max_length=255) length = models.DecimalField(default=0, max_digits=5, decimal_places=2) auth_period_from = models.CharField(max_length=100) auth_period_to = models.CharField(max_length=100) class Net(models.Model): net_id = models.IntegerField(primary_key=True, default = None) prod_date = models.DateField() weight = models.DecimalField(default=0, max_digits=6, decimal_places=2) material = models.CharField(max_length=100) fishing_type = models.CharField(max_length=100, default=None) class Deposit(models.Model): dep_id = models.BigAutoField(primary_key=True, default=None) dep_date = models.DateField() harbour = models.CharField(max_length=100) vessel = models.ForeignKey(Vessel, to_field='VID', on_delete=models.CASCADE) net = models.ForeignKey(Net, to_field='net_id', on_delete=models.CASCADE) amount = models.DecimalField(default=0, max_digits=5, decimal_places=2)
views.py
from django.shortcuts import render, redirect from .models import Vessel from .forms import UploadForm def put_deposit(request): if request.POST: form = UploadForm(request.POST) print(request) if form.is_valid(): form.save() redirect(index) return render(request, 'upload.html', {'form' : UploadForm})
upload.html
<p> Upload </p> <form method="POST" action="{% url 'put_deposit' %}" enctype="multipart/form-data"> {% csrf_token %} {{form}} <button> Submit </button> </form>
排查要点
- views.py核心错误:
redirect(index)未加return,导致POST请求处理后仍执行下方的return render(...),页面刷新但未完成跳转;且index未定义,需替换为urls.py中对应路由的name(如return redirect('index'))。- 表单无效时未将带错误的表单返回前端,无法查看验证失败原因。修正后代码:
def put_deposit(request): if request.method == 'POST': form = UploadForm(request.POST) if form.is_valid(): form.save() return redirect('index') # 表单无效时返回带错误的表单 return render(request, 'upload.html', {'form': form}) # GET请求实例化空表单 form = UploadForm() return render(request, 'upload.html', {'form': form})
- forms.py模型导入缺失:
代码中Vessel.objects.all()和Net.objects.all()未导入对应模型,需在forms.py顶部添加from myapp.models import Deposit, Vessel, Net,否则会触发NameError。 - ModelForm冗余字段定义:
ModelForm会自动根据模型生成字段,无需重复定义dep_date、harbour等字段,可简化为:class UploadForm(ModelForm): class Meta: model = Deposit fields = ['dep_date', 'harbour', 'vessel', 'net', 'amount'] - 模板冗余配置:
表单未上传文件,无需enctype="multipart/form-data",可删除该属性。 - 调试建议:
在views.py的if form.is_valid()前添加print(form.errors),查看表单验证失败的具体原因(如字段格式错误、外键关联不存在等)。
内容的提问来源于stack exchange,提问作者Klitz
相关产品推荐
相关产品推荐

