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

Django中Date、Construction_site与Machinery模型关系及查询问题

Django建筑日程应用模型关系调整方案

现有模型的问题

  1. 单独的Date模型没必要,Django的DateField可以直接存储日期,单独建表会增加关联复杂度
  2. 模型命名不符合Django规范(应使用驼峰式,比如ConstructionSite而非Construction_site),字段名也容易混淆(比如construction_site_name作为多对多字段名,不如直接叫sites清晰)
  3. 现有关联下查询机械需要通过反向关联,容易出错

方案一:调整现有模型实现需求

先修正模型命名和关联关系,让查询更顺畅:

from django.db import models

# 重命名为DateEntry避免和内置date类型冲突,同时设置日期唯一
class DateEntry(models.Model):
    date = models.DateField(unique=True)

    def __str__(self):
        return str(self.date)

class ConstructionSite(models.Model):
    name = models.CharField(max_length=50)
    # 用related_name指定反向关联名称,避免默认的construction_site_set
    dates = models.ManyToManyField(DateEntry, related_name='sites')

    def __str__(self):
        return self.name

class Machinery(models.Model):
    name = models.CharField(max_length=50)
    # 同样用related_name指定反向关联,方便从工地查机械
    sites = models.ManyToManyField(ConstructionSite, related_name='machineries')

    def __str__(self):
        return self.name

视图查询代码

def date_schedule(request):
    # 获取指定日期的条目
    target_date = DateEntry.objects.get(id=1)
    # 通过related_name直接拿到该日期下的所有工地
    construction_sites = target_date.sites.all()
    # 预加载工地对应的机械,减少数据库查询次数
    construction_sites = construction_sites.prefetch_related('machineries')
    return render(request, 'schedule.html', {'construction_sites': construction_sites})

模板示例(schedule.html)

{% for site in construction_sites %}
    <h2>{{ site.name }}</h2>
    <h3>当日使用机械:</h3>
    <ul>
        {% for machine in site.machineries.all %}
            <li>{{ machine.name }}</li>
        {% endfor %}
    </ul>
{% endfor %}

方案二:更贴合业务逻辑的模型重构

考虑到业务是「每日施工安排」,可以直接建立每日安排模型,关联日期、工地和机械,逻辑更清晰:

from django.db import models

class ConstructionSite(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class Machinery(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class DailySchedule(models.Model):
    date = models.DateField()
    # 外键关联工地,一个安排对应一个工地
    site = models.ForeignKey(ConstructionSite, on_delete=models.CASCADE, related_name='daily_schedules')
    # 多对多关联机械,一个工地一天可用多台机械
    machines = models.ManyToManyField(Machinery, related_name='assigned_schedules')

    class Meta:
        # 确保同一个工地同一天只有一条安排
        unique_together = ('date', 'site')

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

视图查询代码

def date_schedule(request):
    # 可以直接用日期字符串查询,比如'2024-05-20'
    target_date = '2024-05-20'
    # 预加载工地和机械,提升查询效率
    schedules = DailySchedule.objects.filter(date=target_date).select_related('site').prefetch_related('machines')
    return render(request, 'schedule.html', {'schedules': schedules})

模板示例(schedule.html)

{% for schedule in schedules %}
    <h2>{{ schedule.site.name }}</h2>
    <h3>日期:{{ schedule.date }}</h3>
    <h3>使用机械:</h3>
    <ul>
        {% for machine in schedule.machines.all %}
            <li>{{ machine.name }}</li>
        {% endfor %}
    </ul>
{% endfor %}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 06:49:51