# How to leverage CBVs with User authentication properly with Mixins

**URL:** <https://forum.djangoproject.com/t/how-to-leverage-cbvs-with-user-authentication-properly-with-mixins/16250>\
**Category:** Forms & APIs\
**Created:** [September 29, 2022, 10:32am UTC](https://forum.djangoproject.com/t/how-to-leverage-cbvs-with-user-authentication-properly-with-mixins/16250 "2022-09-29T10:32:57Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Drone4four](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/drone4four/32/3072_2.png) [@Drone4four](https://forum.djangoproject.com/u/Drone4four)\
**Post date:** [September 29, 2022, 10:32am UTC](https://forum.djangoproject.com/t/how-to-leverage-cbvs-with-user-authentication-properly-with-mixins/16250/1 "2022-09-29T10:32:57Z")

</div>

I’m exploring Class Based Views for the first time and I have a rudimentary Django CMS that is working quite well to my delight. Next I am exploring how to implement Django’s authentication and sessions feature which I can’t seem to get working as intended.

**What works:**

1. Django is serving a template facilitated by a ListView CBV on the landing page at an address like this: [http://127.0.0.1:8000/](http://127.0.0.1:8000/)
2. The list of hyperlinks presented on that page take the web visitor to the corresponding detail page as indicated by a DetailView and identified by a unique slug.
3. I’ve already got a basic custom `login` page: [http://127.0.0.1:8000/accounts/login/](http://127.0.0.1:8000/accounts/login/)  
and a `logout` button which then redirects the user to this location: [http://127.0.0.1:8000/accounts/logout/](http://127.0.0.1:8000/accounts/logout/)
4. I have created non-Admin user credentials which Django will accept. I can add permissions in the Admin Dashboard.

You can see the above listed features by checking out this mirror of my local dev server: [https://8ff1-2607-fea8-87e3-3200-00-a0f5.ngrok.io/](https://8ff1-2607-fea8-87e3-3200-00-a0f5.ngrok.io/)  
However please be advised that Chrome may alert you to a potential phishing attack. To access the site, you may need to bypass the phishing warning.

**What doesn’t work:**  
The problem with the above is that with or without valid credentials, any web visitor can still view all the content.

1. When a user is signed out, the web visitor is still able to traverse and descend down into the other content.
2. I’m trying to get the home page to present the web visitor with the login page requiring every web visitor to enter their credentials. But right now, Django serves all the other content.

_My question:_ How do I get the User authentication Mixins to properly require valid login credentials? Right now everything is open to the public, even though I have added Mixins and tried implementing a custom LoginView, as described below

**What I have tried:**

I tried adding this path to my top-level project `urls.py`:

```auto
from contents.views import CustomLoginView
...
path('', CustomLoginView.as_view(),name='home'),

```

I accompanied the inclusion of the above path entry with this code in my views.py:

```auto
class CustomLoginView(LoginView):
   #template_name = 'registration/login.html'
   fields = ' __all__'
   redirect_authenticated_user = True

   # def get_success_url(self):
   # return reverse_lazy('/')

```

As you can see above, there are some lines which are commented out. I have tried running my server with those lines commented in and commented out. No dice.

It’s also worth pointing out that at the top of my `views.py` I included: `from django.contrib.auth.mixins import LoginRequiredMixin` and also added `LoginRequiredMixin` as an argument inside every single CBV, like in this code snippet:

```auto
class InductionDetailView(DetailView, LoginRequiredMixin):
   model = Induction
   context_object_name = 'inductions'

```

I did that for all the other models.

I created these (non-Admin) credentials for web visitor to test but given that Chrome shows it is a non-secure site, CSRF token mechanism kicks in, preventing you from continuing. But I thought I would include this anyway just in case:

- Username: superdave
- Password: osbourne12  
`https://8ff1-2607-fea8-87e3-3200-00-a0f5.ngrok.io/accounts/logout/`  
`https://8ff1-2607-fea8-87e3-3200-00-a0f5.ngrok.io/accounts/login/`

**My code base:**

_hypnos\_juicer/urls.py_ (project level urls):

```auto
from django.contrib import admin
from django.urls import path, include
# from contents.views import CustomLoginView
 
urlpatterns = [
   path('admin/', admin.site.urls),
   # path('', CustomLoginView.as_view(),name='home'),
   path('accounts/',include('django.contrib.auth.urls')),
   path('', include('contents.urls')),
   # path('classroom/', include('classroom.urls')),
]
 

```

_contents/urls.py_ (app urls):

```auto
from django.urls import path, include
from .views import ContentListView, InductionDetailView,ResearchDetailView, PreambleDetailView, ScriptSuggestionDetailView,StockScriptDetailView, index
 
app_name = 'contents'
 
urlpatterns = [
   path('', ContentListView.as_view(),name='home'),
   path('preambling/<str:slug>', PreambleDetailView.as_view(),name='preamble_details'),
   path('inductioning/<str:slug>', InductionDetailView.as_view(),name='induction_details'),
   path('scripting/<str:slug>', ScriptSuggestionDetailView.as_view(),name='scriptsuggestion_detail'),
   path('stock_scripting/<str:slug>', StockScriptDetailView.as_view(),name='stockscript_detail'),
   path('researching/<str:slug>', ResearchDetailView.as_view(),name='research_detail'),
]

```

_views.py_ (app):

```auto
from django.shortcuts import render
from django.urls import reverse_lazy
from django.views.generic import ListView,DetailView
from .models import Preamble, Induction, Research, ScriptSuggestion,StockScript,Content
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.views import LoginView
from django.contrib.auth.decorators import login_required
''' class CustomLoginView(LoginView):
   #template_name = 'registration/login.html'
   fields = ' __all__'
   redirect_authenticated_user = True
 
   #def get_success_url(self):
   # return reverse_lazy('/')
'''
def index(request):
   return render(request,'contents/index.html')
 
class ContentListView(ListView, LoginRequiredMixin):
   # model_list.html
   # model = Induction
   model = Content
   # template_name = 'home.html'
  
   # fields =['author','title',]
  
   def get_context_data(self, **kwargs):
       # Call the base implementation first to get a context
       context = super(ContentListView, self).get_context_data(**kwargs)
       # Add in a QuerySet of all the Baklawa
       context['inductions'] = Induction.objects.all()
       context['preambles'] = Preamble.objects.all()
       context['research'] = Research.objects.all()
       context['scriptsuggestions'] = ScriptSuggestion.objects.all()
       context['stockscripts'] = StockScript.objects.all()
       return context
 
class PreambleDetailView(DetailView, LoginRequiredMixin):
   model = Preamble
   context_object_name = 'preambles'
 
class InductionDetailView(DetailView, LoginRequiredMixin):
   model = Induction
   context_object_name = 'inductions'
  
class ScriptSuggestionDetailView(DetailView, LoginRequiredMixin):
   model = ScriptSuggestion
   context_object_name = 'scriptsuggestions'
 
class StockScriptDetailView(DetailView, LoginRequiredMixin):
   model = StockScript
   context_object_name = 'stockscripts'
 
 
class ResearchDetailView(DetailView, LoginRequiredMixin):
   model = Research
   context_object_name = 'research'
 

```

_models.py_ (app):

```auto
from django.db import models
 
class Content(models.Model):
   pass
 
# Create your models here.
class Preamble(models.Model):
   title = models.CharField(max_length=300,blank=True)
   body = models.TextField(max_length=300000,blank=True)
   author = models.CharField(max_length=30,blank=True)
   slug = models.SlugField(unique=True,blank=True)
   # posting_date = models.DateField(auto_now=False, auto_now_add=False, **options), https://docs.djangoproject.com/en/4.1/ref/models/fields/#django.db.models.DateField
  
   def __str__ (self):
       return f'{self.title}'
  
class Induction(models.Model):
   title = models.CharField(max_length=300,blank=True)
   body = models.TextField(max_length=300000,blank=True)
   author = models.CharField(max_length=30,blank=True)
   slug = models.SlugField(unique=True,blank=True)
  
   def __str__ (self):
       return f'{self.title}'
 
class ScriptSuggestion(models.Model):
   title = models.CharField(max_length=300,blank=True)
   body = models.TextField(max_length=300000,blank=True)
   author = models.CharField(max_length=300,blank=True)
   slug = models.SlugField(unique=True,blank=True)
 
   def __str__ (self):
       return f'{self.title}'
 
class Research(models.Model):
   title = models.CharField(max_length=300,blank=True)
   body = models.TextField(max_length=300000,blank=True)
   author = models.CharField(max_length=300,blank=True)
   slug = models.SlugField(unique=True,blank=True)
 
   def __str__ (self):
       return f'{self.title}'
 
class StockScript(models.Model):
   title = models.CharField(max_length=300,blank=True)
   body = models.TextField(max_length=300000,blank=True)
   author = models.CharField(max_length=300,blank=True)
   slug = models.SlugField(unique=True,blank=True)
 
   def __str__ (self):
       return f'{self.title}'

```

_models.py_:

```auto
from django.db import models
 
class Content(models.Model):
   pass
 
# Create your models here.
class Preamble(models.Model):
   title = models.CharField(max_length=300,blank=True)
   body = models.TextField(max_length=300000,blank=True)
   author = models.CharField(max_length=30,blank=True)
   slug = models.SlugField(unique=True,blank=True)
   # posting_date = models.DateField(auto_now=False, auto_now_add=False, **options), https://docs.djangoproject.com/en/4.1/ref/models/fields/#django.db.models.DateField
  
   def __str__ (self):
       return f'{self.title}'
  
class Induction(models.Model):
   title = models.CharField(max_length=300,blank=True)
   body = models.TextField(max_length=300000,blank=True)
   author = models.CharField(max_length=30,blank=True)
   slug = models.SlugField(unique=True,blank=True)
  
   def __str__ (self):
       return f'{self.title}'
 
class ScriptSuggestion(models.Model):
   title = models.CharField(max_length=300,blank=True)
   body = models.TextField(max_length=300000,blank=True)
   author = models.CharField(max_length=300,blank=True)
   slug = models.SlugField(unique=True,blank=True)
 
   def __str__ (self):
       return f'{self.title}'
 
class Research(models.Model):
   title = models.CharField(max_length=300,blank=True)
   body = models.TextField(max_length=300000,blank=True)
   author = models.CharField(max_length=300,blank=True)
   slug = models.SlugField(unique=True,blank=True)
 
   def __str__ (self):
       return f'{self.title}'
 
class StockScript(models.Model):
   title = models.CharField(max_length=300,blank=True)
   body = models.TextField(max_length=300000,blank=True)
   author = models.CharField(max_length=300,blank=True)
   slug = models.SlugField(unique=True,blank=True)
 
   def __str__ (self):
       return f'{self.title}'

```

**Resources I have used so far:**

- This is the course I am taking: [Django 4 and Python Full-Stack Developer Masterclass](https://www.udemy.com/course/django-and-python-full-stack-developer-masterclass/)
- [Introduction to class-based views | Django documentation | Django](https://docs.djangoproject.com/en/4.1/topics/class-based-views/intro/)
- [Class-based views | Django documentation | Django](https://docs.djangoproject.com/en/4.1/topics/class-based-views/)
- [Using mixins with class-based views | Django documentation | Django](https://docs.djangoproject.com/en/4.1/topics/class-based-views/mixins/)

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [September 29, 2022, 11:49am UTC](https://forum.djangoproject.com/t/how-to-leverage-cbvs-with-user-authentication-properly-with-mixins/16250/2 "2022-09-29T11:49:32Z")

</div>

You are oh-so-close.

Unfortunately, the only reference you missed listing is the one with the specific answer to your issue.

See [The LoginRequiredMixin](https://docs.djangoproject.com/en/4.1/topics/auth/default/#the-loginrequired-mixin)

Specifically, the very first paragraph in which it says:

> This mixin should be at the leftmost position in the inheritance list.

> [@Drone4four](#):
>
> It’s also worth pointing out that at the top of my `views.py` I included: `from django.contrib.auth.mixins import LoginRequiredMixin` and also added `LoginRequiredMixin` as an argument inside every single CBV, like in this code snippet:

I’ll point out here that `LoginRequiredMixin` is not an “argument” to the class. These are class definitions, so this mixin is a base class being used in the construction of your view class.

If this distinction isn’t clear, or to just enhance your understanding of CBVs and topics related to them, I would suggest you spend some time learning about Python classes, class inheritance, and the MRO. (This becomes more important when you look at extending or enhancing the functionality of these CBVs.)

---

<div class="post-metadata">

**Author:** ![Drone4four](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/drone4four/32/3072_2.png) [@Drone4four](https://forum.djangoproject.com/u/Drone4four)\
**Post date:** [October 2, 2022, 10:56am UTC](https://forum.djangoproject.com/t/how-to-leverage-cbvs-with-user-authentication-properly-with-mixins/16250/3 "2022-10-02T10:56:43Z")

</div>

> [@KenWhitesell](#):
>
> You are oh-so-close.
> 
> Unfortunately, the only reference you missed listing is the one with the specific answer to your issue.
> 
> See [The LoginRequiredMixin](https://docs.djangoproject.com/en/4.1/topics/auth/default/#the-loginrequired-mixin)
> 
> Specifically, the very first paragraph in which it says:
> 
> > This mixin should be at the leftmost position in the inheritance list.

Hi @KenWhitesell! Thanks for the reply. This answers my question. For all my CBV’s in my app’s `views.py` I swapped the position of the `LoginRequiredMixin` in the class constructor. That achieves what I have set out to accompish for now. My website is now protected and the user login credentials work beautifully.

I’ve got big plans to extend this web app. When I come up with more questions I will be sure to report back here.

> [@KenWhitesell](#):
>
> I’ll point out here that `LoginRequiredMixin` is not an “argument” to the class. These are class definitions, so this mixin is a base class being used in the construction of your view class.  
> If this distinction isn’t clear, or to just enhance your understanding of CBVs and topics related to them, I would suggest you spend some time learning about Python classes, class inheritance, and the MRO. (This becomes more important when you look at extending or enhancing the functionality of these CBVs.)

Noted. My project so far is a rudimentary Django CMS like a blog. I am able to get away with using basic CBVs. No need yet to build advanced features. One day maybe I will get there.

Improving my overall Python chops in general is a great idea which will then enable me to write my own Django middleware and take my Django views to the next-level.

In 2020 I completed 32 PyBites on: [https://codechalleng.es/](https://codechalleng.es/)  
Earlier this year I completed 14 exercises on [https://exercism.org/](https://exercism.org/)

These two destinations on the web are excellent resources for learning Python. Continuing to work on those Python challenges, specifically with classes, will be my next step to expand my ability to build Django projects.
