Получение данных поля M2M в шаблоне Django

Я хочу получить данные m2m в моем шаблоне через представления, но не могу этого сделать. Дело в том, что я могу показать данные поля m2m, зацикливая их из самого шаблона, но это замедляет работу сайта.

Моя модель командных приложений выглядит следующим образом:

class Team(models.Model):
    title = models.CharField(max_length=255)
    team_country = CountryField(max_length=200, blank=True, null=True)          
    members = models.ManyToManyField(User, related_name='teams')
    created_by = models.ForeignKey(User, related_name='created_teams', on_delete=models.CASCADE)

Теперь в моем турнирном приложении я пытаюсь получить "членов" команды.

Мои турнирные представления выглядят следующим образом:

def tournament_page(request, slug):
    page = 'tournament_page'
    user = request.user
    tournament = Tournament.objects.get(slug=slug)
    players = tournament.participants.select_related('user')
    all_players = Profile.objects.select_related('user')
    side_tourneys_ongoing = Tournament.objects.filter(state='Ongoing')[:10]
    side_tourneys_upcoming = Tournament.objects.filter(state='Upcoming')[:10]
    side_tourneys_completed = Tournament.objects.filter(state='Completed')[:10]
    teams = Team.objects.select_related('created_by')
        
         
    
context = {
    'page': page,
    'tournament': tournament, 
    'side_tourneys_ongoing': side_tourneys_ongoing,
    'side_tourneys_upcoming': side_tourneys_upcoming,
    'side_tourneys_completed': side_tourneys_completed, 
    'teams': teams, 
    'players':players, 
    'all_players':all_players
}

Теперь я могу показать команды с их членами в шаблоне, используя цикл for в самом шаблоне, как:

Html шаблон

<div class="grid-x">
    {% for team in teams %}
    {% for player in players %}
    {% if team.id == player.active_team_id and team.game == tournament.game %}
    <div class="wf-card event-team">
        <div> {{team.title}} </div>
        <div class="event-team-players">            
            {% for member in team.members.all %}            
                {{ member.username }}    
            {% endfor %}                                  
        </div>
    </div>
    {% endif %}
    {% endfor %}
    {% endfor %}           
</div>

Что я хочу, так это использовать этот фрагмент кода

{% for member in team.members.all %}            
   {{ member.username }}    
{% endfor %}

в моих представлениях, поскольку это приводит к замедлению работы сайта, и я не знаю почему.

Что я пробовал в своих представлениях, это:

all_teams = Team.objects.all()

members = all_teams.members.all()

и

members = Team.objects.all().prefetch_related('members')

Первый выдает ошибку:

У объекта 'QuerySet' нет атрибута 'members'

Второй показывает много пустых записей

Пробовал почти все с помощью поиска, но ни один из них не помог, кроме использования кода, который я предоставил непосредственно в самом шаблоне.

Думаю, у вас уже есть эта информация. Вы ограничиваете появление игрока только player.active_team, а не всеми его командами, поэтому вам не нужно делать отдельный вызов. Я подозреваю, что ваши циклы player и member таким образом также удваиваются - вы делаете sql вызов team.members.all для каждого игрока*каждой команды как есть Вот один способ обработки, который может работать немного лучше (непроверенный код, извините)

    <div class="grid-x">
    {% for team in teams %}
        {% if team.game == tournament.game %}
         <div class="wf-card event-team">
             <div> {{team.title}} </div>
             <div class="event-team-players">   
             {% for player in players %}
                 {% if team.id == player.active_team_id  %}           
                     {{ player.user.username }}
                 {% endif %}  
              {% endfor %}                  
              </div>
         </div>
         {% endif %}
     {% endfor %}      
     </div>

Если вы хотите, чтобы игрок отображался во всех своих командах, вы можете попробовать получить информацию о командах одновременно с помощью prefetch_related

players = tournament.participants.select_related('user').prefetch_related('user__teams')

тогда в вашем шаблоне вы можете просто посмотреть, находится ли текущая команда в связанной группе команд.

         {% for player in players %}
             <div class="event-team-players">   
             {% if team in player.user.teams  %}           
                  {{ player.user.username }}
             {% endif %}  
          {% endfor %}  

Это немного эффективнее, так как вся информация о командах предварительно загружена, поэтому вам не нужно вызывать sql для каждой команды.

Вернуться на верх