How to improve the structure of my django project?

Oops good night, recently I started studying django and I came across the problem of structuring the project. Using the codes as an example (suppose you have 1 billion business rules there), I rewrote the user model (user, works perfectly), created a custom manager custom queryset, views (which already comes in startapp) and created a service (another name for “put the business rule”). And my doubts are: 1 ° - Is this basic structure correct? 2 ° - What could I change to further improve the structure of the project? 3 - What is the best way to call my services? static method, instance or class method? 4 - Is it better to put the services of each application in class or to separate everything into functions? 5 ° - If I have a function call from a service view and this function calls another internal function, is it better to instantiate a class to be able to call the functions with the self or to position the function above the other to be able to call?

models.py

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.db.models import Q
from .manager import UserManager

class User(AbstractBaseUser):

    REQUIRED_FIELDS = ['name', 'email', 'password']
    
    USERNAME_FIELD = 'login'
    
    name = models.CharField(name='name',max_length=100, null=False)
    email = models.EmailField(name='email',unique=True)
    login = models.CharField(name='login',max_length=30, null=False, unique=True)
    password = models.CharField(name='password',max_length=255,null=False)
    profile_photo = models.ImageField(name='profilePhoto',upload_to='profilePhotos', null=True, blank=True)
    date_birth = models.DateField(name='dateBirth',null=True)
    is_active = models.BooleanField(name='active',default=True)
    is_admin = models.BooleanField(name='admin',default=False)
    menus = models.ManyToManyField('menu.Menu', db_table='SFT_USER_MENU')
    company = models.ForeignKey(to='company.Company', on_delete=models.RESTRICT, null=True)
    created_at = models.DateTimeField(name='createdAt',auto_now_add=True)
    updated_at = models.DateTimeField(name='updatedAt',auto_now_add=True)

    objects = UserManager()
    
    @property
    def is_superuser(self):
        return self.is_admin

    class Meta:
        db_table = 'SFT_USER'
    
    def __str__(self):
        return self.name;

manager.py

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from .queryset import UserQuerySet

class UserManager(BaseUserManager):
    def create_user(self, login, name, password, email, is_active=False, is_staff=False, is_admin=False):
        if not login:
            raise ValueError('Login must be set!')
        user = self.model(login=login, email=email, name=name)
        user.is_active=is_active
        user.is_staff=is_staff
        user.is_admin=is_admin
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, login, name, password, email):
        user = self.create_user(login, name, password, email,is_active=True, is_staff=True, is_admin=True)
        user.save(using=self._db)
        return user
    
    def get_queryset(self):
        return UserQuerySet(model=self.model, using=self._db, hints=self._hints)
    
    def listUsersByCompany(self, company):
        return self.get_queryset().listUsersByCompany(company)

views.py

from django.http import HttpResponse, HttpResponse
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .models import User
from .forms import UserForm
from django_datatables_view.base_datatable_view import BaseDatatableView
from django.views import View
from .service import UserService

@login_required
def find(request):
    if request.method == 'GET':
        data = request.GET
        value = data['value']
        field = data['field']
        
        #Call to services
        user = UserService.findByFieldAndValue(field, value)
        
        if user is not None and len(user) > 0:
            return HttpResponse(status=409)
        
    return HttpResponse(status=200)

class UserIndexView(View):
    def get(self, request):
        return render(request, 'user/index.html')
    
    def post(self, request):
        pass
    
class UserCreateView(View):
    def get(self, request):
        return render(request, 'user/create.html')
    
    def post(self, request):
        pass

class UserBaseDatatableView(BaseDatatableView):
    model = User
    columns = ['id', 'name', 'email', 'createdAt']
    max_display_length = 10
    
    def get_filter_method(self):            
        return 'icontains'

service.py

from .models import User

class UserService():
    
    @staticmethod
    def findByFieldAndValue(field: str, value: str):
        return User.objects.findByFieldAndValue(field, value)

Welcome @GiovanniFelicio !

This is a highly opinionated topic, with many different perspectives.

In addition to the linked material directly above, I suggest you see:

Personally, I’ve never found the need or seen a value to anything that I see people refer to as a “service layer”.

1 Like