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

如何基于Django模型生成带自增唯一主键的跟踪数据报告

解决方案

一、先修正现有模型的基础问题

你现有模型有几个语法和规范问题先调整,调整后可以直接得到你要的自增跟踪ID,同时天然支持分批次录入数据:

from django.db import models
from django.core.validators import RegexValidator

# 假设你已提前定义好CourseChoices模型和batch_pattern校验规则
batch_pattern = RegexValidator(r'^[0-9A-Z-]+$', '仅支持字母、数字和横杠')

class Student(models.Model):
    # 修正参数拼写错误:primarykey改为primary_key
    roll_number = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=50)
    email = models.EmailField(max_length=60)
    city = models.CharField(max_length=20)

    def __str__(self):
        return f"{self.roll_number}-{self.name}"

class Course(models.Model):
    # 外键字段命名为student更符合语义,自动关联Student的roll_number主键
    student = models.ForeignKey(Student, on_delete=models.CASCADE, related_name='courses')
    course = models.ForeignKey(CourseChoices, on_delete=models.CASCADE)

class Fee(models.Model):
    # Django默认会给未显式指定主键的模型新增自增id字段,直接作为交易跟踪ID使用即可
    student = models.ForeignKey(Student, on_delete=models.CASCADE, related_name='fee_records')
    amount_to_be_paid = models.DecimalField(max_digits=7, decimal_places=2, default=0)
    discount = models.DecimalField(max_digits=5, decimal_places=2, default=0)
    # 统一改为蛇形命名,符合Django编码规范
    final_amount_to_be_paid = models.DecimalField(max_digits=7, decimal_places=2, default=0)
    amount_received = models.DecimalField(max_digits=7, decimal_places=2, default=0)
    balance = models.DecimalField(max_digits=7, decimal_places=2, default=0)
    batch = models.CharField(validators=[batch_pattern], max_length=20)

调整后三个模型完全独立,支持分批次录入:先录入学生基础信息,后续随时可以给已存在的学生补充录入选课、缴费数据,不需要一次性提交所有字段。

二、合并数据展示实现

方案1:Django Admin后台快速实现

如果你要在Django自带的后台展示合并报告,直接自定义Fee模型的Admin配置即可:

from django.contrib import admin
from .models import Student, Course, Fee

@admin.register(Fee)
class FeeAdmin(admin.ModelAdmin):
    # list_display配置展示列,id就是你需要的自增唯一跟踪ID
    list_display = ('id', 'get_student_roll', 'get_student_name', 'get_student_email', 'get_courses', 'amount_to_be_paid', 'discount', 'final_amount_to_be_paid', 'amount_received', 'balance', 'batch')
    list_filter = ('batch', 'student__city')
    search_fields = ('student__roll_number', 'student__name', 'batch')

    # 自定义方法拉取学生基础信息
    def get_student_roll(self, obj):
        return obj.student.roll_number
    get_student_roll.short_description = '学号'

    def get_student_name(self, obj):
        return obj.student.name
    get_student_name.short_description = '姓名'

    def get_student_email(self, obj):
        return obj.student.email
    get_student_email.short_description = '邮箱'

    # 自定义方法拉取学生所有选课信息
    def get_courses(self, obj):
        return "、".join([c.course.name for c in obj.student.courses.all()])
    get_courses.short_description = '所选课程'

配置完成后,Fee模型的后台列表页就会直接展示三张表合并的所有数据。

方案2:自定义视图/报告实现

如果要在前端页面或者导出报告里展示,用Django ORM关联查询即可,不需要额外新建模型:

# 视图层查询代码,一次性关联查询所有数据,避免N+1性能问题
from .models import Fee

def fee_report(request):
    fee_records = Fee.objects.select_related('student').prefetch_related('student__courses').all()
    # 传到模板里循环渲染即可,每条记录的id就是唯一跟踪ID
    return render(request, 'fee_report.html', {'fee_records': fee_records})

模板层循环渲染示例:

<table border="1">
  <tr>
    <th>跟踪ID</th>
    <th>学号</th>
    <th>姓名</th>
    <th>邮箱</th>
    <th>城市</th>
    <th>所选课程</th>
    <th>应缴金额</th>
    <th>折扣</th>
    <th>实际应缴</th>
    <th>已缴金额</th>
    <th>余额</th>
    <th>批次</th>
  </tr>
  {% for fee in fee_records %}
  <tr>
    <td>{{ fee.id }}</td>
    <td>{{ fee.student.roll_number }}</td>
    <td>{{ fee.student.name }}</td>
    <td>{{ fee.student.email }}</td>
    <td>{{ fee.student.city }}</td>
    <td>{% for course in fee.student.courses.all %}{{ course.course.name }}、{% endfor %}</td>
    <td>{{ fee.amount_to_be_paid }}</td>
    <td>{{ fee.discount }}</td>
    <td>{{ fee.final_amount_to_be_paid }}</td>
    <td>{{ fee.amount_received }}</td>
    <td>{{ fee.balance }}</td>
    <td>{{ fee.batch }}</td>
  </tr>
  {% endfor %}
</table>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 10:24:00