Search code examples
djangodjango-templatesdjango-viewsdjango-urlsdjango-allauth

How can i make a certain template visible only to confirmed users in Django?


I'm creating a site and I successfully added an email confirmation system using django-allauth. Now I would like to have some parts of my site available only to users who confirmed their email.

Suppose that part looks something like this:

{% extends "main/header.html" %}
{% if user.is_authenticated %}
{% block content %}


<body>



<div>
    <p> Here are are a bunch of features etc... </p>
</div>          



</body>

{% endblock %}
{% endif %}

Now, I know how to do that in theory, but not practically. I figured that I need to add a statement that checks if the email is confirmed. What I'm not understanding is where should I add this statement and what that should look like. Should it be on the template? Or should I create a view for this? Any advice is appreciated? Thanks in advance!


Solution

  • I think its best to put the login in your CustomUser Model:

    class CustomUser(AbstractUser):
    
        @property
        def has_verified_email(self):
            return self.emailaddress_set.filter(verified=True,primary=True).exists()
    

    Then use in template:

     {% if user.has_verified_email %}
        // some lines 
     {% endif %}
    

    If you haven't overridden your User model, then you can put it in a separate model which has a OneToOne relation to your User model:

    class Profile(models.Model):
            user = models.OneToOneField(User)
    
            @property
            def has_verified_email(self):
                return self.user.emailaddress_set.filter(verified=True,primary=True).exists()
    

    Then use it in template:

     {% if user.profile.has_verified_email %}
        // some lines 
     {% endif %}
    

    Second best option would be to use in View, but you will need to put the same logic in every view. If you are using a Class Based View, you can make a Mixin and use it in them:

    class SomeMixin(object):
         def get_context_data(self, *args, **kwargs):
             context = super(SomeMixin, self).get_context_data(*args, **kwargs)
             context['has_verified_email'] = self.request.user.emailaddress_set.filter(verified=True,primary=True).exists()
             return context
    
    class ActualView(SomeMixin, TemplateView):
         # subclassing from the mixin in
    
    // template code
     {% if has_verified_email %}
        // some lines 
     {% endif %}