Django项目前端插入记录时自动存储当前用户及月份唯一性验证实现咨询
解决方案
嘿,我来帮你搞定这两个需求,结合你现有的代码一步步来修改:
1. 先更新数据库模型(models.py)
首先咱们得给graphinput模型加两个关键配置:关联登录用户的字段,还有用户+月份的联合唯一性约束——这样数据库层面就能直接拦住同一用户重复提交同月份的数据,最靠谱。
修改后的models.py代码:
from django.db import models from django.contrib.auth.models import User # 导入Django自带的用户模型 class graphinput(models.Model): # 关联当前登录用户,用户删除时该用户的所有数据也跟着删除 user = models.ForeignKey(User, on_delete=models.CASCADE) Month = models.CharField(max_length=30) Values = models.IntegerField() class Meta: # 设置联合唯一约束:同一个用户的月份不能重复 constraints = [ models.UniqueConstraint(fields=['user', 'Month'], name='unique_user_month') ]
改完模型记得执行数据库迁移命令更新表结构:
python manage.py makemigrations python manage.py migrate
2. 重构视图逻辑(views.py)
接下来改视图,要实现自动获取当前登录用户、批量处理表单数据,还要过滤空值和重复数据。我把你重复的代码改成循环了,以后维护起来也方便:
from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required # 加登录验证,未登录不让提交 from input.models import graphinput from .utils import get_plot # 装饰器确保只有登录用户能访问这个页面,未登录会跳转到登录页(需在settings.py配置LOGIN_URL) @login_required def index(request): if request.method == 'POST': # 把12组月份和值的字段名配对,避免写12次重复代码 month_value_pairs = [ ('JanMonth', 'JanValue'), ('FebMonth', 'FebValue'), ('MarMonth', 'MarValue'), ('AprMonth', 'AprValue'), ('MayMonth', 'MayValue'), ('JunMonth', 'JunValue'), ('JulMonth', 'JulValue'), ('AugMonth', 'AugValue'), ('SepMonth', 'SepValue'), ('OctMonth', 'OctValue'), ('NovMonth', 'NovValue'), ('DecMonth', 'DecValue'), ] current_user = request.user # 直接取当前登录的用户,不用前端传 for month_field, value_field in month_value_pairs: # 取出表单值并去掉前后空格 month = request.POST.get(month_field, '').strip() value_str = request.POST.get(value_field, '').strip() # 跳过空的月份或值,避免存储无效数据 if not month or not value_str: continue # 把值转成整数,这里可以加错误提示,比如用户输入非数字的情况 try: value = int(value_str) except ValueError: # 可以用Django的messages给前端弹提示,比如"XX月份的值不是有效数字" continue # 尝试创建数据,模型加了唯一约束,重复的话会报错,捕获后跳过即可 try: graphinput.objects.create(user=current_user, Month=month, Values=value) except Exception as e: # 判断是不是唯一约束冲突的错误,是的话跳过这条 if 'unique_user_month' in str(e): print(f"用户{current_user.username}已经有{month}月的数据啦,跳过这条") else: # 其他错误正常抛出,方便调试 raise print('有效数据都添加成功啦!') return redirect('graphvalue') else: return render(request, 'bp.html')
几个额外的小建议
- 前端表单可以把月份输入改成下拉选择框,避免用户输入格式不一致(比如"1月"和"Jan"被当成不同月份),示例:
<label>Month1:</label> <select name="JanMonth"> <option value="">选个月份</option> <option value="Jan">一月</option> <option value="Feb">二月</option> <!-- 剩下的月份依次添加 --> </select>
- 可以用Django的
messages框架给用户返回反馈,比如哪些月份重复了、哪些数据成功添加,用户体验更好。 - 别忘了配置登录相关的路由和页面,不然
@login_required会跳转到默认登录页,你可以在settings.py里加LOGIN_URL = '/你的登录页路由/'。
这样两个需求就都实现啦:自动存储当前登录用户,同一用户不能重复提交同月份的数据。
内容的提问来源于stack exchange,提问作者Bhavesh R
相关产品推荐
相关产品推荐

