Как вызвать функцию в шаблоне django с помощью условий

У меня есть модель для группы:

class Group(models.Model):
   leader = models.ForeignKey(User, on_delete=models.CASCADE)
   name = models.CharField(max_length=55)
   description = models.TextField()
   joined = models.ManyToManyField(User, blank=True)
   size = models.BooleanField(default=False)
   max_size = models.IntegerField(default=10)
   closed = models.BooleanField(default=False, blank=True)

Идея заключается в том, что пользователи могут вступать в группы (тем самым увеличивая общее количество joined для этой группы) и покидать группы. Они делают это через следующее представление:

def join_group(request, pk):
    id_user = request.user.id
    group = Group.objects.get(id=request.POST.get('group_id'))
    account = Account.objects.get(user_id=id_user)
    
    if group.joined.filter(id=request.user.id).exists():
        group.joined.remove(request.user)
        account.joined_groups.remove(group)
    else: 
        group.joined.add(request.user)
        account.joined_groups.add(group)

    return HttpResponseRedirect(reverse('group_detail', args=[str(pk)]))

И шаблон:

{% if user.is_authenticated %}
  <form action="{% url 'join_group' group.pk %}" method="POST">
    {% if group.closed == True %} 
      <div>Sorry, this group is closed</div>
    {% else %}
    {% csrf_token %}
      {% if joined %}
        <button type="submit" name="group_id" value="{{group.id}}">LEAVE</button>
      {% else %}
        <button type="submit" name="group_id" value="{{group.id}}">JOIN</button>  
      {% endif %}
    {% endif %}
  </form>
{% endif %}

Пользователи, вступающие в группы и выходящие из них, работают нормально, но я пытаюсь реализовать то, что когда total_joined == group.max_size вызывается функция для close группы. Поскольку на данный момент единственный способ закрыть группу - это чтобы пользователь, который ее создал, пошел и обновил группу, чтобы изменить closed=True.

Я пытаюсь вызвать функцию в шаблоне, чтобы закрыть группу, когда она достигнет максимальной вместимости (или max_size). Основное условие работает, но я не знаю, как вызвать функцию или даже как отредактировать текущую группу, чтобы изменить closed=True:

{% if group.total_joined == group.max_size %}
   {{ close_group function would go here }}
{% endif %}

представление close_group:

def close_chaburah(request, pk):
    group = get_object_or_404(Group, id=request.POST.get('group_id'))
    chaburah.closed == True
    return HttpResponseRedirect(reverse('group_detail', args=[str(pk)]))

Есть ли способ вызвать эту функцию один раз group.total_joined == group.max_size используя мое условие или она должна быть запущена другим способом. Или это должно быть сделано в представлении join_group?

Для проверки условия я закодировал ссылку на вызов функции для закрытия группы:

{% if group.total_joined == group.max_size %}
   <a href="{% url 'close_group' group.pk %}">Close Group</a>
{% endif %}

Это сработало в том смысле, что ссылка появилась, когда условие было выполнено, но когда я щелкнул по ссылке, я получил ошибку group.models.Group.DoesNotExist: Group matching query does not exist

Есть ли лучший способ закрыть группу? Должен ли я вызывать функцию с условием в представлении? Или я должен вызывать ее в шаблоне? Должна ли она быть в join_group или в конкретной функции close_group?

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

class Group(models.Model):
   ...

   @property
   def is_full(self):
       return self.total_joined == self.max_size

Затем я бы включил сигнал post_save, который проверяет свойство is_full и обновляет closed, если это так:

@receiver(models.signals.post_save, sender=Group)
def set_closed(sender, instance, using, **kwargs):
    if instance.is_full and not self.closed:
        instance.closed = True
        instance.save()
    elif not instance.is_full and self.closed:
        instance.closed = False
        instance.save()

Для этого вы можете захотеть выполнить проверку ac в вашей функции join до добавления пользователя и после добавления пользователя. Таким образом, если группа заполнена, вы можете вернуть это в представление, или если пользователь последним присоединился к группе, вы можете закрыть ее. Может сработать что-то вроде этого:

def check_group(group):
    if group.max_size == group.size AND group.closed == False:
        # Closes group because it has rached max size
        group.closed = True
        group.save()
        # returns True since group has reached max size
        return group.closed
    elif group.max_size == group.size:
        # Still returns True because the group is closed
        return group.closed
    else:
        # Returns False since group is not max size or closed, new member can be added
        return group.closed

Вызовите эту функцию один раз перед попыткой добавить участника в группу. Если возвращается False, добавьте участника, если возвращается true, сообщите ему, что группа переполнена. Затем вызовите эту функцию еще раз после добавления участника, чтобы узнать, нужно ли закрыть группу после его присоединения.

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