I know I can create user groups and assign permission to them from the admin area in a django project. I can also create a group and assign permission to it by importing 
You can define a post_migrate signal to create required User and Group model instances if they don't exist already. 
When you create an application in using python manage.py startapp <app_name>, it creates an AppConfig class in apps.py file.
You can specify which signal to call in AppConfig class definition. Say the signal is called populate_models. In that case, modify AppConfig to look like following:
from django.apps import AppConfig
from django.db.models.signals import post_migrate
class AppConfig(AppConfig):
    name = 'app'
    def ready(self):
        from .signals import populate_models
        post_migrate.connect(populate_models, sender=self)
And in signals.py define the populate_models function.
def populate_models(sender, **kwargs):
    from django.contrib.auth.models import User
    from django.contrib.auth.models import group
    # create groups
    # assign permissions to groups
    # create users
Here is the code for adding all existing permissions of an app under a Group. For exemple if you have App1 and App2, and you want to automatically create 2 groups named app1 and app2 containing permissions to the models of each app (respectively), try this :
from django.apps import AppConfig
from django.db.models.signals import post_migrate
class App1Config(AppConfig):
    name = 'app1'
    def ready(self):
        from .signals import populate_models
        post_migrate.connect(populate_models, sender=self)
def populate_models(sender, **kwargs):
    from django.apps import apps
    from .apps import App1Config
    from django.contrib.auth.models import Group, Permission
    from django.contrib.contenttypes.models import ContentType
    group_app, created = Group.objects.get_or_create(name=App1Config.name)
    models = apps.all_models[App1Config.name]
    for model in models:
        content_type = ContentType.objects.get(
            app_label=App1Config.name,
            model=model
        )
        permissions = Permission.objects.filter(content_type=content_type)
        group_app.permissions.add(*permissions)
Do the same for App2
Then assign users to their groups.
For usage :
from .apps import App1Config
def is_in_group_app1(user):
    return user.groups.filter(name=App1Config.name).exists() 
from django.contrib.auth.decorators import login_required, user_passes_test
from .permissions import is_in_group_app1
@login_required(login_url='where_to_redirect')
@user_passes_test(is_in_group_app1) 
def myview(request):
    # Do your processing
For CBV :
@method_decorator(user_passes_test(is_in_group_app1), name='dispatch')
class LogListView(ListView):
    """ Displays all logs saved on App1 """
    model= Logger.objects.order_by('-date_created')
from django import template
from app1.permissions import is_in_group_app1
register = template.Library()
@register.filter
def has_perms(user):
    return is_in_group_app1(user)
{% load has_perms %}
{% if request.user|has_perms %}
    <li class="nav-item">
        <a href="{% url 'app1:log' %}" class="nav-link">
            <i class="icon-history"></i>
            <span data-i18n="nav.dash.main">App1 Log</span>
        </a>
    </li>
{% endif %}
It took me a while to find all this process, so if it can help others :