djangodjango-viewsdjango-templatesdjango-postgresql

how to call function in django template using conditionals


I have a model for Group:

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)

The idea is that Users can join groups (thus adding to the total joined for that Group) and leave groups. They do that through this view:

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)]))

And template:

{% 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 %}

Users joining and leaving groups works fine, the thing I'm trying to implement is when the total_joined == group.max_size a function would be called to close the group. Since, as of now the only way too close a Group is for the User who created it to go and update the Group to change closed=True.

What I'm trying to do is call a function within the template to close the Group when it's reached max capacity ( or max_size). The basic conditional works but I don't know how to call the function or even how to edit the current Group to change closed=True:

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

the close_group view:

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)]))

Is there a way to call this function once group.total_joined == group.max_size using my conditional or does it have to triggered in a different way. Or should it be done in the join_group view?

To test the conditional I hardcoded a link to call the function to close a Group:

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

This worked in the sense that the link showed up when the conditional was met, but when I clicked the link I got an error group.models.Group.DoesNotExist: Group matching query does not exist

Is there a better way to close a Group? Should I be calling the function with the conditional in the view? Or should I call it in the template? Should it be in join_group or in a specific close_group function?


Solution

  • For this, you might want to perform ac check in your join function prior to adding the user and after adding the user. This way, if the group is full, you can return that to the view, or if the user is the last to join the group, you can then close it. something like this may work:

    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
    

    Call this once before trying to add the member to the group. If it returns False, add the member, if it returns true, tell them the group is full. Then call this again after the member is added to see if the group needs to be closed now that they have joined.