Apps
We have the following models:
Note
This app now requires a Contact
app (see get_contact_model
)
so we can exclude (soft) deleted contacts.
Permissions
Does a user have access to an app e.g. the MyApps.CRM
app:
from apps.models import App
from example_apps.models import MyApps
App.objects.has_access(user, MyApps.CRM)
Note
Created 11/06/2023, There may be a better way to do this!
For the tests, see example_apps/tests/test_app.py
.
Models
App
The App
model contains the properties of the apps in a project
e.g. name
, icon
…
Tip
The user_apps
method is used to display a list of apps for a user.
e.g. AppListView
Useful methods include:
admin_apps
: List of apps where the user is an administrator.admin_app_groups
: List of apps where the user is a group administrator.app_menu
: Can be used to control the main menu in the projectcurrent_app_admin
can be used to enable menu options for a user who is an administrator for the current app.show_app_menu
will tell you if the user has access to just one app i.e. no need to show the app menu unless they have access to several apps.
app_perms
: Check the source code for documentation.create_app
: Create a new app…is_administrator
: Is the user an administrator for this app?is_administrator_for_any_app
: Is the user an administrator for any app?user_apps
: Apps available to this user.user_dash_url
: Dashboard URL for this user (if there is a single one).
This model includes a slug
, name
, menu
caption and icon
for the
app.
administrators
(many to many): Users who can administer the app.app_group
(many to many): Users belonging to these groups (AppGroup
) have permission to access the app.global_group
(many to many): Users belonging to these groups (DjangoGroup
) have permission to access the app.hide_app_groups
(boolean): Does the app useapp_group
(or not)?url_contact_edit
andurl_dash
are URLs for the dashboard and contact edit pages for the app.
AppSettings
app_superusers
(many to many): Users who can set the administrator for an app.contact_administrators
(many to many): Users who can create / update / delete users (or contacts).
AppGroup
and AppGroupUser
List of groups for an application. These are different to the Django Group
.
Templates
You can add the following to your base.html
template:
{% block menu %}
{% if user.is_authenticated %}
{% if app_menu and app_menu.show_app_menu %}
<li class="pure-menu-item{% if 'apps' in path %} pure-menu-selected{% endif %}">
<a href="{% url 'apps.list' %}" class="pure-menu-link">
<i class="fa fa-bullseye fa-fw"></i>
Apps
</a>
</li>
{% endif %}
{% if app_menu and app_menu.current_app %}
<li class="pure-menu-item{% if app_menu.current_app.url_dash == request.build_absolute_uri %} pure-menu-selected{% endif %}">
<a href="{{ app_menu.current_app.url_dash }}" class="pure-menu-link">
<i class="fa fa-dashboard fa-fw"></i>
Dashboard
</a>
</li>
{% endif %}
{% if app_menu and app_menu.show_settings %}
<li class="pure-menu-item{% if 'settings' in path %} pure-menu-selected{% endif %}">
<a href="{% url 'project.settings' %}" class="pure-menu-link">
<i class="fa fa-cog fa-fw"></i>
Settings
</a>
</li>
{% endif %}
{% endif %}
{% endblock menu %}
Views
To add details of the app_menu
to the context
of BaseMixin
, we use
the BASE_MIXIN_CONTEXT_PLUGIN
system:
Add the following to settings/base.py
:
# See 'base/view_utils.py'
BASE_MIXIN_CONTEXT_PLUGIN = ["apps.plugin.AppBaseMixin"]
Set the current_app_slug
if your template is for a particular app e.g:
class DashView(LoginRequiredMixin, BaseMixin, TemplateView):
current_app_slug = MyApps.REPORT
template_name = "example/dash.html"
Settings
The Settings view needs access to various permissions:
from braces.views import LoginRequiredMixin, UserPassesTestMixin
from django.views.generic import DetailView
from apps.views import is_contact_or_app_admin, SettingsBaseMixin
class SettingsView(
LoginRequiredMixin, UserPassesTestMixin, SettingsBaseMixin, TemplateView
):
template_name = "example/settings.html"
def test_func(self, user):
return is_contact_or_app_admin(user)
The permissions returned by SettingsBaseMixin
will work with the following:
{% block content %}
<div class="pure-g">
{% include 'apps/_settings_apps.html' %}
{% include 'apps/_settings_groups.html' %}
</div>
{% endblock content %}