Home > Net >  how to call function in django template using conditionals
how to call function in django template using conditionals

Time:07-19

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?

CodePudding user response:

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.

CodePudding user response:

I would create a Model method that checks whether the group is full or not, you can then use this in your template and view more easily then recreating any logic.

class Group(models.Model):
   ...

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

I would then include a post_save signal that checks the is_full property and updates closed if so:

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