Search code examples
djangodjango-modelsdjango-viewsdjango-permissions

How to link AbstractUser to Group and query in Views for Business Logic


I have limited the amount of files a user can upload to my site using a logical query in my upload app's views.py file. Long story short, after the user has uploaded 5 files, they are redirected to a page that says they must become a premium member.

I am now trying to add to that logic by checking if they are in the "Free User" group. If they are not, they should be allowed to upload an unlimited number of files.

So far I have used the admin panel to create two groups. One is "Free User" and one is "Gold User".

I gave both groups add, change, delete, view permissions for my "beatupload" app.

I added this code to my users models.py

# users/models.py
from django.contrib.auth.models import AbstractUser, Group
from django.db import models

class CustomUser(AbstractUser):
    pass
    # add additional fields in here
    group = models.ForeignKey(Group, on_delete=models.CASCADE, default=1)


    def __str__(self):
        return self.email

I see that I have a field in my users_customuser table for group_id, but when I change the group in the admin interface no changes reflect.

When I check the table using select * from auth_group I see that I have id and group name, being Free User and Gold User.

I am trying to use this query in my upload views.py:

class uploadNew(CreateView): # new
    model = beat
    fields = ['title', 'beat']

    success_url = reverse_lazy('uploads')


    #Check number of beats uploaded by user and if exceeds require signup


    def get_template_names(self):
        if (beat.objects.filter(producer=self.request.user).count() <= 4 and user.groups.filter(name='Free User').exists()):
            return ['uploadNew.html',]
        else:
            return ['becomeMember.html',]

    # END CHECK #
    def form_valid(self, form):
        form.instance.producer = self.request.user
        return super(uploadNew, self).form_valid(form)

So somehow I am not linking my custom user to the group correctly, and there is no checking what group the user is in to either allow unlimited uploads or require becoming a Gold User.

Please let me know if you need to see more code, and also explain for a beginner if possible, noting what areas I may be weak in and need to read more of in Django's documentation. I am on 2.2.2 by the way.


Solution

  • After creating the groups in admin panel and verifying that a relationship exists when executing

    SELECT * from users_customuser_groups;

    I was able to get my intended results with the following code:

    if (beat.objects.filter(producer=self.request.user).count() == 5 and self.request.user.groups.filter(name="Free User").exists()):

    My full models code is posted below for reference. The app name is 'users'

    # users/models.py
    from django.contrib.auth.models import AbstractUser, Group
    from django.db import models
    
    class CustomUser(AbstractUser):
        pass
        # add additional fields in here
        group = models.ForeignKey(Group, on_delete=models.CASCADE, default=1)
    
    
        def __str__(self):
            return self.email
    
    
    
    

    VIEWS:

    #beatupload/views.py
    from django.shortcuts import render
    from django.views.generic import ListView, CreateView
    from django.urls import reverse_lazy
    
    from .forms import beatUploadForm #new
    from .models import beat
    
    
    # Create your views here.
    class UploadView(ListView):
        model = beat
        template_name = 'uploads.html'
        def get_queryset(self):
            return beat.objects.filter(producer=self.request.user)
    
    class uploadNew(CreateView): # new
        model = beat
        fields = ['title', 'beat']
    
        success_url = reverse_lazy('uploads')
        #Check number of beats uploaded by user and if exceeds amount require signup
        #To render sign up template if true and proceed to upload if false
    
        def get_template_names(self):
            if (beat.objects.filter(producer=self.request.user).count() == 5 and self.request.user.groups.filter(name="Free User").exists()):
                return ['becomeMember.html',]
            else:
                return ['uploadNew.html',]
    
        # END CHECK #
        def form_valid(self, form):
            form.instance.producer = self.request.user
            return super(uploadNew, self).form_valid(form)