首页 > 解决方案 > 列出用户,包含有关这些用户的大量数据。如何为每个用户将一对多表中的最后一条记录添加到该列表中?

问题描述

我的问题:

每个用户有多个合同(有些有 0 个)。我正在尝试为每个用户获取具有最高开始日期的合同,并在此列表中显示它的开始日期和结束日期。

模型:

class Contract(models.Model):
  user = models.ForeignKey(User, on_delete = models.CASCADE, related_name='contracts')
  contract_start = models.DateField(null = True, blank = True)
  contract_end = models.DateField(null = True, blank = True)

看法:

def get(self, request):
  users = User.objects.all().exclude(is_superuser=True)
  return render(request, 'user/list_all.html', {
        'users': users,
    }) 

模板:

{% for user in users %}
  <tr>
    <td>{{ user.employee.number }}</td>
    <td>{{ user.last_name }}</td>
    <td>{{ user.first_name }}</td>
    <td>{{ user.employee.location }}</td>

    <td>{{ Contract Start }}</td>
    <td>{{ Contract End }}</td>

  </tr>
{% endfor %}

我已经忙了一天了,但似乎无法解决它。我不能使用distinct(),因为我正在使用 MySQL。我一直在尝试使用annotate,但我要么得到一个包含每个用户的查询集,而有些没有合同,要么我为每个用户获得相同的合同日期。

标签: djangodjango-modelsdjango-templatesdjango-views

解决方案


据我了解,您希望获得最高的开始日期,这意味着最新的合同日期

所以首先我们需要获取每个用户的合约

然后我们需要根据最新的 contract_start 字段过滤合同,这可能不是最好的解决方案,但我可以做到

看法

def get(self, request):
  users = User.objects.all().exclude(is_superuser=True)
  data = {}
  for user in users:
    user_contracts = Contract.objects.filter(user=user)
     # edit: to make sure it will not throw matching query does not exist error
    if len(user_contracts ) > 0: 
        user_latest = user_contracts.latest('contract_start')
        data[user] =  user_latest
    else:
        data[user] = ''

  return render(request, 'user/list_all.html', {
        'data': data,
    }) 

模板:


{% for user, contract in data.items %}
  <tr>
    <td>{{ user.employee.number }}</td>
    <td>{{ user.last_name }}</td>
    <td>{{ user.first_name }}</td>
    <td>{{ user.employee.location }}</td>

    <td>{{ contract.contract_start  }}</td>
    <td>{{ contract.contract_end }}</td>

  </tr>
{% endfor %}

latest 根据给定字段返回表中的最新对象。 https://docs.djangoproject.com/en/dev/ref/models/querysets/#latest


推荐阅读