You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中实现重复鸡体重记录的覆盖确认功能

解决方案

问题分析

你当前的实现存在两个核心问题:

  • 重复确认页面的表单未携带用户输入的体重数据,点击"Overwrite"后无法获取要覆盖的数值
  • 视图函数中缺少处理覆盖确认请求的逻辑分支

具体修改步骤

1. 更新视图函数,传递用户输入的体重并处理覆盖请求

修改views.py中的add_record函数,在捕获重复错误时保存用户输入的体重,同时新增处理覆盖POST请求的逻辑:

# views.py
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import redirect, render
from .models import Chicken, Record
from .forms import RecordForm
from datetime import datetime

def add_record(request, chicken) -> HttpResponseRedirect | HttpResponse:
    """
    View for the "record_weight.html" 
    Post & Get methods
    """
    if request.method == "POST":
        # 处理覆盖确认的请求
        if request.POST.get('overwrite') == 'yes':
            chicken_obj = Chicken.objects.filter(number=chicken).first()
            if not chicken_obj:
                raise Http404("Bird does not exist")
            
            # 获取用户之前输入的体重和日期
            new_weight = request.POST.get('weight')
            record_date = datetime.now().date()
            
            # 找到当天的旧记录并更新
            old_record = Record.objects.filter(chicken=chicken_obj, date=record_date).first()
            if old_record:
                old_record.weight = new_weight
                old_record.save()
            return redirect("/admin/tags/record/")

        # 处理初始的体重提交请求
        form = RecordForm(request.POST)
        if form.is_valid():
            record = form.save(commit=False)
            record.chicken = Chicken.objects.filter(number=chicken).first()
            record.date = datetime.now().date()
            try:
                Record.save(record)
            except ValidationError:
                # 传递用户输入的体重到确认页面
                return render(request, "tags/duplicate_record.html", {
                    "bird": record.chicken,
                    "new_weight": record.weight  # 把用户输入的体重传过去
                }) 
            return redirect("/admin/tags/record/") 

    form = RecordForm()
    try:
        birds = Chicken.objects.all()
        req_bird = birds.filter(number=chicken).first()
    except Chicken.DoesNotExist:
        raise Http404("Bird does not exist")
    
    req_records = Record.objects.filter(chicken_id=chicken).order_by("-date")  # 简化倒序写法
    return render(request, "tags/record_weight.html", {
        "bird": req_bird, 
        "records": req_records, 
        "form": form, 
        "nav_filter": get_birds_navbar(birds)
    })

2. 修改确认页面表单,携带体重数据并使用POST请求

更新duplicate_record.html,把表单改成POST方法,用隐藏字段保存新体重,同时调整按钮逻辑:

# duplicate_records.html (styling removed for easier reading)

{% extends "tags/layout.html" %}

{% block content %}
<div>
    <div>
        <h2>There is already a weight for today!</h2>
        <p>Do you want to overwrite that entry with the new weight: {{ new_weight }}?</p>
        <form method="POST">
            {% csrf_token %}
            <!-- 隐藏字段保存新体重和覆盖标识 -->
            <input type="hidden" name="weight" value="{{ new_weight }}">
            <input type="hidden" name="overwrite" value="yes">
            
            <a href="/records/{{ bird.number }}">No</a>
            <button type="submit">Overwrite</button>
        </form>
    </div>
</div>
{% endblock %}

3. 确保模型层的唯一约束正确

你的Record模型需要有针对chicken和date的唯一约束,示例如下:

# models.py
from django.db import models

class Record(models.Model):
    chicken = models.ForeignKey(Chicken, on_delete=models.CASCADE)
    date = models.DateField()
    weight = models.DecimalField(max_digits=5, decimal_places=2)

    class Meta:
        unique_together = ('chicken', 'date')  # 确保同一只鸡同一天只有一条记录

这样当用户提交重复记录时,Record.save()会抛出ValidationError,触发确认流程。

逻辑说明

  1. 用户提交体重后,如果当天已有记录,视图捕获ValidationError,将用户输入的体重传递到确认页面
  2. 确认页面显示新体重,表单通过POST请求携带体重数据和覆盖标识
  3. 视图收到覆盖请求后,找到当天的旧记录并更新体重,完成覆盖操作

内容的提问来源于stack exchange,提问作者quietCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 20:32:41