Organizations-App-Referenz¶
Die Organizations-App bietet Mandantenfähigkeit mit rollenbasierter Zugriffskontrolle (RBAC). Benutzer können mehreren Organisationen angehören, jede mit eigenen Einstellungen, Mitgliedern und Daten. Diese App ist die Grundlage, von der alle anderen Apps für Berechtigungsprüfungen und Datenfilterung abhängen.
Übersicht¶
Speicherort: app/organizations/
Zweck: Mandantenfähige Organisationsverwaltung mit RBAC
Wichtige Modelle: Organization, OrganizationMembership, OrganizationInvitation, OrganizationSettings
Verwendet von: Alle anderen Apps hängen von dieser App für Berechtigungsprüfungen, organisationsbezogene Datenfilterung und Berechtigungs-Mixins ab.
Dateistruktur¶
organizations/
├── models.py # 4 Modelle
├── views/ # Views-Paket (3 Module)
│ ├── __init__.py # Re-exportiert alle 16 Views
│ ├── organization_views.py # 5 CBVs + 3 FBVs (CRUD, Wechsel, Einstellungen)
│ ├── member_views.py # 3 FBVs (Mitgliederliste, Entfernen, Rollenwechsel)
│ └── invitation_views.py # 5 FBVs (Senden, Liste, Annehmen, Ablehnen, Meine)
├── forms.py # OrganizationSettingsForm
├── urls.py # 16 URL-Patterns
├── signals.py # Auto-Erstellung Standard-Org bei Benutzererstellung
├── middleware.py # OrganizationMiddleware + switch_organization()
├── utils.py # 11 Berechtigungs-Hilfsfunktionen
├── mixins.py # OrgPermissionMixin, DelegatedPermissionMixin
├── admin.py # Django-Admin-Konfiguration (4 Model-Admins + 1 Inline)
├── services/
│ ├── __init__.py
│ └── numbering_service.py # Chargen-/Eimer-Nummerierung
└── templates/organizations/ # 13 HTML-Templates
Modelle¶
Siehe Datenbankmodelle - Organizations-App für vollständige Feldreferenz.
Organization¶
Mandantenfähige Entität. Felder umfassen Name, org_type (personal/family/cooperative/commercial/club), Beschreibung, Logo (auf 300x300px skaliert) und Aktiv-Status.
Wichtige Methoden:
get_owners()-- QuerySet der Inhaber-Benutzerget_admins()-- QuerySet der Admin- und Inhaber-Benutzeruser_is_member(user)-- booluser_role(user)-- Rollen-String oder None
OrganizationMembership¶
Benutzer-Organisations-Beziehung mit rollenbasiertem Zugriff. Erzwingt eine Eindeutigkeitsbedingung auf (organization, user).
Rollen: owner, admin, member, viewer
Wichtige Methoden:
can_manage_members()-- nur owner/admincan_delete_organization()-- nur ownercan_edit_resources()-- owner/admin/membercan_delete_resources()-- nur owner/admin
OrganizationInvitation¶
E-Mail-Einladungssystem mit UUID-Tokens, 7-Tage-Ablauf und Status-Verfolgung (pending/accepted/declined/expired).
Status-Übergänge: pending kann zu accepted, declined oder expired wechseln. Alle drei sind Endzustände.
Wichtige Methoden:
is_valid()-- prüft, ob ausstehend und nicht abgelaufen; markiert automatisch als abgelaufen, wenn das Ablaufdatum überschritten istaccept(user)-- erstellt Mitgliedschaft und markiert als akzeptiertdecline()-- markiert als abgelehnteffective_status-- Property, das den wahren Status einschließlich impliziter Ablaufs berechnet
OrganizationSettings¶
Organisationsspezifische Einstellungen: Datumsformat, Zeitzone, Einheitensystem, Sprache, Branding-Farben (primär/sekundär), MFA-Richtlinie, E-Mail-Benachrichtigungseinstellungen und Chargen-/Eimer-Nummerierungsvorlagen.
Middleware¶
OrganizationMiddleware¶
Speicherort: app/organizations/middleware.py
Fügt jeder Anfrage Organisationskontext hinzu:
| Attribut | Beschreibung |
|---|---|
request.current_organization |
Aktive Organisation (oder None für den "Alle Organisationen"-Modus) |
request.user_organizations |
Alle Organisationen des Benutzers (QuerySet) |
request.org_colors |
Organisations-Branding-Farben (Dict mit primary- und secondary-Schlüsseln) |
Priorität der Organisationsauswahl:
- Session-Variable
current_organization_id(Benutzer hat Organisation gewechselt oder "Alle" gewählt) - Erste Organisation nach Mitgliedschafts-Beitrittsdatum
- None (nicht authentifiziert)
Wenn der Session-Wert explizit auf None gesetzt ist, sieht der Benutzer Daten aus allen seinen Organisationen. Wenn die Session-Variable fehlt, verwendet das System standardmäßig die erste Organisation.
switch_organization() -- Hilfsfunktion zum Wechseln der aktuellen Organisation via Session. Übergeben Sie None, um zur "Alle Organisationen"-Ansicht zu wechseln.
Berechtigungs-Hilfsfunktionen¶
Speicherort: app/organizations/utils.py
11 Funktionen für zentralisierte Berechtigungsprüfungen:
get_user_role(user, organization) # Gibt Rolle oder None zurück
get_user_organizations(user) # Gibt QuerySet zurück
user_is_member(user, organization) # Gibt bool zurück
user_can_view(user, resource) # Gibt bool zurück
user_can_create(user, organization) # Gibt bool zurück
user_can_edit(user, resource) # Gibt bool zurück
user_can_delete(user, resource) # Gibt bool zurück
user_can_manage_members(user, organization) # Gibt bool zurück
user_can_delete_org(user, organization) # Gibt bool zurück
user_can_change_org_settings(user, org) # Gibt bool zurück
filter_by_user_organizations(queryset, user, request) # Gibt gefiltertes QuerySet zurück
Berechtigungsmatrix:
| Aktion | Inhaber | Admin | Mitglied | Betrachter |
|---|---|---|---|---|
| Ressourcen anzeigen | Ja | Ja | Ja | Ja |
| Ressourcen erstellen | Ja | Ja | Ja | Nein |
| Eigene Ressourcen bearbeiten | Ja | Ja | Ja | Nein |
| Alle Ressourcen bearbeiten | Ja | Ja | Nein | Nein |
| Ressourcen löschen | Ja | Ja | Nein | Nein |
| Mitglieder verwalten | Ja | Ja | Nein | Nein |
| Einstellungen ändern | Ja | Ja | Nein | Nein |
| Organisation löschen | Ja | Nein | Nein | Nein |
Siehe Berechtigungssystem für detaillierte Dokumentation.
Berechtigungs-Mixins¶
Speicherort: app/organizations/mixins.py
OrgPermissionMixin¶
Wiederverwendbarer Model-Mixin für organisationsbasierte Berechtigungsprüfung. Fügen Sie ihn zu jedem Modell hinzu, das einen organization-ForeignKey und optional ein created_by-Feld hat.
Methoden:
user_can_view(user)-- jedes aktive Organisationsmitglied kann anzeigenuser_can_edit(user)-- Admins/Inhaber können alles bearbeiten; Mitglieder können eigene Datensätze bearbeitenuser_can_delete(user)-- nur Admins/Inhaber können löschen
Konfiguration: Setzen Sie das Klassenattribut permission_owner_field auf den Namen des Feldes, das den Ersteller des Datensatzes speichert (Standard: 'created_by').
Verwendet von: QueenBreeding, ColonySplit, InventoryItem, InventoryTransaction, ProductSale, WarehouseLocation
DelegatedPermissionMixin¶
Mixin für untergeordnete Modelle, die Berechtigungsprüfungen an ein übergeordnetes Modell delegieren (z.B. Statusänderungsdatensätze, die Berechtigungen von ihrer übergeordneten Entität erben).
Konfiguration: Setzen Sie das Klassenattribut permission_delegate_field auf den Namen des ForeignKey, der auf das übergeordnete Modell verweist.
Verwendet von: BreedingStatusChange (delegiert an breeding), SplitStatusChange (delegiert an split)
Views¶
Organisation CRUD¶
| View | Typ | Zweck |
|---|---|---|
| OrganizationListView | CBV | Liste aller Organisationen des Benutzers mit Mitgliederzahlen |
| OrganizationDetailView | CBV | Organisationsdetails, Mitglieder, Bienenstock-/Aktivitätsstatistiken |
| OrganizationCreateView | CBV | Organisation erstellen, automatisch Inhaber-Mitgliedschaft für Ersteller |
| OrganizationUpdateView | CBV | Organisationsdetails aktualisieren (Name, Typ, Beschreibung, Logo) |
| OrganizationDeleteView | CBV | Löschen mit Kaskaden-Warnung und Anzeige abhängiger Datenzahlen |
| switch_org_view | FBV | Zu anderer Organisation wechseln |
| switch_to_all_orgs_view | FBV | Zu "Alle Organisationen"-Ansicht wechseln |
| organization_settings_view | FBV | Organisationseinstellungen anzeigen und aktualisieren |
Mitgliederverwaltung¶
| View | Typ | Zweck |
|---|---|---|
| member_list_view | FBV | Aktive Mitglieder mit Rollen auflisten |
| member_remove_view | FBV | Mitglied entfernen (verhindert Selbstentfernung und Inhaber-Entfernung durch Nicht-Inhaber) |
| member_role_change_view | FBV | Mitgliederrolle ändern (nur Inhaber können zum Inhaber befördern) |
Einladungsverwaltung¶
| View | Typ | Zweck |
|---|---|---|
| invitation_send_view | FBV | E-Mail-Einladung senden, Duplikate und bestehende Mitglieder validieren |
| invitation_list_view | FBV | Alle Einladungen für eine Organisation auflisten |
| invitation_accept_view | FBV | Einladung annehmen, E-Mail-Übereinstimmung prüfen, Mitgliedschaft erstellen |
| invitation_decline_view | FBV | Einladung ablehnen, E-Mail-Übereinstimmung prüfen |
| my_invitations_view | FBV | Gültige ausstehende Einladungen für den aktuellen Benutzer anzeigen |
Formulare¶
OrganizationSettingsForm¶
Speicherort: app/organizations/forms.py
Formular zur Bearbeitung von Organisationseinstellungen.
Felder: date_format, time_zone, unit_system, language, primary_color, secondary_color, E-Mail-Benachrichtigungsschalter, Chargen-/Eimer-Nummerierungsformat-Felder (einschließlich benutzerdefinierter Formateingaben).
Widgets: HTML5-Farbwähler für Branding-Farben, Auswahl-Dropdowns für Nummerierungsformat, Texteingaben für benutzerdefinierte Nummerierungsvorlagen.
Validierung: Benutzerdefinierte Chargen- und Eimer-Format-Validierung über NumberingValidator, wenn die Option "Benutzerdefiniert" ausgewählt ist.
Services¶
NumberingService¶
Speicherort: app/organizations/services/numbering_service.py
Generiert Chargen- und Eimer-Kennungen mit konfigurierbaren Vorlagen.
Wichtige Methoden:
generate_charge_identifier(organization, honey_type, harvest_year)-- gibt str zurückgenerate_bucket_number(organization, charge_identifier)-- gibt str zurück
Verwendet select_for_update() für thread-sichere Sequenz-Inkrementierung.
Tokens: {YEAR}, {TYPE}, {LABEL}, {SEQ} für Chargen; {CHARGE}, {SEQ}, {EIMER}, {BUCKET} für Eimer.
NumberingValidator¶
Validiert benutzerdefinierte Nummerierungsvorlagen. Prüft Token-Existenz, Format-Spezifikationen und Eindeutigkeitsanforderungen.
Signale¶
create_default_organization¶
- Auslöser:
post_saveauf User (nur bei Erstellung) - Aktion: Erstellt automatisch eine persönliche Organisation namens "{username}'s Beekeeping" mit Inhaber-Mitgliedschaft für jeden neuen Benutzer
- Zweck: Stellt sicher, dass alle Daten von Anfang an einer Organisation zugehören
URL-Patterns¶
organizations/ → OrganizationListView (organization-list)
organizations/create/ → OrganizationCreateView (organization-create)
organizations/<pk>/ → OrganizationDetailView (organization-detail)
organizations/<pk>/edit/ → OrganizationUpdateView (organization-update)
organizations/<pk>/delete/ → OrganizationDeleteView (organization-delete)
organizations/<pk>/switch/ → switch_org_view (organization-switch)
organizations/switch/all/ → switch_to_all_orgs_view (organization-switch-all)
organizations/<pk>/members/ → member_list_view (member-list)
organizations/<pk>/members/<user_id>/remove/ → member_remove_view (member-remove)
organizations/<pk>/members/<user_id>/change-role/ → member_role_change_view (member-role-change)
organizations/<pk>/invite/ → invitation_send_view (invitation-send)
organizations/<pk>/invitations/ → invitation_list_view (invitation-list)
organizations/invitations/accept/<token>/ → invitation_accept_view (invitation-accept)
organizations/invitations/decline/<token>/ → invitation_decline_view (invitation-decline)
organizations/my-invitations/ → my_invitations_view (my-invitations)
organizations/<pk>/settings/ → organization_settings_view (organization-settings)