Python django-如何将表的记录与从另一个表计算的计数值绑定

Python django-如何将表的记录与从另一个表计算的计数值绑定,python,sql,django,Python,Sql,Django,在我的申请表中,我有一份培训清单。此列表上的一个字段应显示每个培训的预订数量。 为了说明我的意思,我准备了SQL查询: SELECT * FROM club_training a LEFT JOIN (SELECT training_id, count(*) FROM club_booking group by training_id) b ON a.id = b.training_id 你能给我一些建议在django怎么做吗? 我在代码中使用了Booking.objects.all()。应显

在我的申请表中,我有一份培训清单。此列表上的一个字段应显示每个培训的预订数量。 为了说明我的意思,我准备了SQL查询:

SELECT *
FROM club_training a
LEFT JOIN
(SELECT training_id, count(*)
FROM club_booking
group by training_id) b
ON a.id = b.training_id
你能给我一些建议在django怎么做吗? 我在代码中使用了
Booking.objects.all()。应显示一个适用于每次培训的计数值

views.py

class HomePageView(TemplateView):
    """Home Page with list of trainings"""
    template_name = 'club/training_list.html'


    def get_context_data(self, **kwargs):
        now = datetime.datetime.now()
        context = super(HomePageView, self).get_context_data(**kwargs)
        context['trainings'] = Training.objects.filter(state="A", training_date__gte=now).order_by('training_date', 'start_time')
        for each_training in context['trainings']:       
            each_training.diff = each_training.availability - each_training.counter
            each_training.counter = Booking.objects.all().values('training_id').annotate(booked_amount=Count('training_id'))
        return context 
models.py

class Training(models.Model):
    """Class for plan training"""
    STATE = (
        ('A', 'Active'),
        ('I', 'Inactive'),
    )
    name = models.ForeignKey('TrnDesc')
    instructor = models.ForeignKey('Instructor')
    start_time = models.TimeField(blank=True)
    end_time = models.TimeField(default='00:00:00')
    availability = models.PositiveIntegerField(default=15)
    state = models.CharField(max_length=1, choices=STATE, default='A')
    training_date = models.DateField(default=date.today)
    counter = models.PositiveIntegerField(default=0)
    def __str__(self):
        return self.name.name

class Booking(models.Model):
    """Data of people which book fitness classes"""
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    email = models.CharField(max_length=50)
    phone = models.CharField(max_length=10)
    training = models.ForeignKey('Training')
    def __str__(self):
        return self.training.name.name
training_list.html

{% extends 'club/base.html' %}

{% block content %}

        <ul class="nav nav-pills">
            <li role="presentation" class="active"><a href="#">Fitness Classes</a></li>
            <li role="presentation"><a href="#">Join Us</a></li>
            <li role="presentation"><a href="#">Contact Us</a></li>
        </ul>
        <br></br>
    {% regroup trainings by training_date as date_list %}
    {% for date in date_list %}
        <div class="panel panel-default">


            <div class="panel-heading">{{date.grouper|date:"l, d F o"}}</div>


            <table class="table">
                <tr>
                    <th style="width: 20%">Training name</th>
                    <th style="width: 30%">Training description</th>
                    <th style="width: 10%">Instructor</th>
                    <th style="width: 10%">Start time</th>
                    <th style="width: 10%">End time</th>
                    <th style="width: 10%">Left</th>
                    <th style="width: 10%">Test_counter</th>
                    <th style="width: 10%">Actions</th>
                </tr>


                {% for training in date.list %}

                <tr>
                    <td>{{training.name}}</td>
                    <td>{{training.name.desc}}</td>
                    <td>{{training.instructor}}</td>
                    <td>{{training.start_time|time:"H:i"}}</td>
                    <td>{{training.end_time|time:"H:i"}}</td>
                    <td>{{training.diff}}</td>
                    <td>{{training.counter}}</td>
                    <td><a href="{% url 'book' training_id=training.pk%}"><button type="button" class="btn btn-primary">Book</button></a></td>
                </tr>

                {% endfor %}    
            </table>
        </div>
    {% endfor %}

{% endblock %}
{%extends'club/base.html%}
{%block content%}


{%按培训日期作为日期列表%重新分组培训} {日期列表%中的日期为%0} {date.gropper}date:“l,dfo”} 培训名称 培训说明 教练 开始时间 结束时间 左边 测试计数器 行动 {%用于date.list%中的培训} {{training.name} {{training.name.desc} {{培训.讲师} {{培训。开始时间{时间:“H:i”} {{培训。结束时间{时间:“H:i”} {{training.diff} {{training.counter}} {%endfor%} {%endfor%} {%endblock%}
我会从另一个方向走近:
每一次训练。预定。计数()

此外,我不确定它是否符合您的数据库目标,但如果我了解您在寻找什么,您可以这样设置:

型号.py

class Training(models.Model):
    ...
    <fields>
    ...
    def __str__(self):
        return self.name.name

    @property
    def counter(self):
        return self.booking_set.count()

    @property
    def diff(self):
        return self.availability - self.counter
from django.db.models import Manager

class Active(Manager):

    def by_date(self, date)
        Training.objects.filter(state="A", training_date__gte=date).order_by('training_date', 'start_time')
from .managers import Courses

class Training(models.Model):
    ...
    <fields>
    objects = models.Manager()
    active = Active()
    ...

    def __str__(self):
        return self.name.name
然后,您可以将管理器添加到模型中(确保保留您的管理器):

型号.py

class Training(models.Model):
    ...
    <fields>
    ...
    def __str__(self):
        return self.name.name

    @property
    def counter(self):
        return self.booking_set.count()

    @property
    def diff(self):
        return self.availability - self.counter
from django.db.models import Manager

class Active(Manager):

    def by_date(self, date)
        Training.objects.filter(state="A", training_date__gte=date).order_by('training_date', 'start_time')
from .managers import Courses

class Training(models.Model):
    ...
    <fields>
    objects = models.Manager()
    active = Active()
    ...

    def __str__(self):
        return self.name.name
我不熟悉您在模板中正在做的一些事情,但是所有事情都应该以现在的方式工作


或者也许我有点不对劲,但希望这是值得思考的:)

如果我做对了,你想得到培训id和所有预订组的预订对象数量,按培训id分组。我理解正确了吗,或者你还想要别的吗?在我的培训列表上,我想显示每个培训的预订对象数(每个培训id)欢迎使用stack overflow:-)请查看@annlii,这是答案之一。但是从技术上讲,如果在
context['trainings']
中存在
n
培训对象,那么您正在对数据库进行
n
数量的
Booking.objects.filter(training\u id=each\u training.id).count()
查询。因此,如果
n
的值增加,您将能够使用DjangDebugToolbar看到页面加载花费的时间太长。而您为SQL编写的等效查询只是一个返回您想要的一切的查询。@AnkushRaghuvanshi感谢您注意到这个问题。现在对我来说还可以,但以后我可能不得不想出更有效的方法。定义
@property
不会将该属性的值存储在数据库中,因此会在需要时进行计算。因此,从技术上讲,如果在页面加载时计算每个对象的计数值,则使用
def counter
只会降低页面加载速度。因此,如果对象数量太多,计算也太慢。