### Set Up Local Development Environment Source: https://github.com/bennylope/django-organizations/blob/master/CONTRIBUTING.rst Install project dependencies and set up a virtual environment for local development. ```bash mkvirtualenv django-organizations cd django-organizations/ pip install -r requirements-dev.txt ``` -------------------------------- ### Install django-organizations Source: https://github.com/bennylope/django-organizations/blob/master/docs/getting_started.rst Install the package using pip. ```bash pip install django-organizations ``` -------------------------------- ### Invitation Backend Usage Example Source: https://github.com/bennylope/django-organizations/blob/master/docs/reference/backends.rst This is the primary interface method for the invitation backend. It should be referenced from your invitation form or view to customize invitation behavior. ```python class AccountUserAddForm(OrganizationUserAddForm): class Meta: model = OrganizationUser ``` -------------------------------- ### Fast Testing with Pytest Source: https://github.com/bennylope/django-organizations/blob/master/README.rst Install test dependencies and use pytest for faster testing within your current environment. Use the -x option for failfast mode. ```bash pip install .[tests] pytest ``` ```bash pytest -x ``` -------------------------------- ### Create Organization and Manage Users with Utility Functions Source: https://github.com/bennylope/django-organizations/blob/master/README.rst Use the `create_organization` utility to create new organizations and associate users. You can also add users to organizations and assign administrative privileges. ```python >>> from organizations.utils import create_organization >>> chris = User.objects.get(username="chris") >>> soundgarden = create_organization(chris, "Soundgarden", org_user_defaults={'is_admin': True}) >>> soundgarden.is_member(chris) True >>> soundgarden.is_admin(chris) True >>> soundgarden.owner.organization_user >>> soundgarden.owner.organization_user.user >>> >>> audioslave = create_organization(chris, "Audioslave") >>> tom = User.objects.get(username="tom") >>> audioslave.add_user(tom, is_admin=True) ``` -------------------------------- ### Include Invitation Backend URLs Source: https://github.com/bennylope/django-organizations/blob/master/docs/reference/backends.rst Configure backend URLs by referring to the backend's get_urls method to allow for registration and user activation. ```python from organizations.backends import invitation_backend urlpatterns = [ url(r'^invitations/', include(invitation_backend().get_urls())), ] ``` -------------------------------- ### Customize Invitation and Registration Backends Source: https://github.com/bennylope/django-organizations/blob/master/docs/getting_started.rst Specify custom backends for invitations and registrations in your project settings. ```python INVITATION_BACKEND = 'myapp.backends.MyInvitationBackend' REGISTRATION_BACKEND = 'myapp.backends.MyRegistrationBackend' ``` -------------------------------- ### User Invitation and Creation Logic Source: https://github.com/bennylope/django-organizations/blob/master/docs/reference/backends.rst This snippet demonstrates the logic within the save method for handling user invitations. It checks for existing users, creates new ones if necessary using the invitation backend, and associates them with the organization. ```python def save(self, *args, **kwargs): try: user = get_user_model().objects.get(email__iexact=self.cleaned_data['email']) except get_user_model().MultipleObjectsReturned: raise forms.ValidationError("This email address has been used multiple times.") except get_user_model().DoesNotExist: user = invitation_backend().invite_by_email( self.cleaned_data['email'], **{'domain': get_current_site(self.request), 'organization': self.organization}) return OrganizationUser.objects.create(user=user, organization=self.organization) ``` -------------------------------- ### Set Registration Backend Source: https://github.com/bennylope/django-organizations/blob/master/docs/reference/settings.rst Specify the full dotted path to the custom registration backend. Defaults to 'organizations.backends.defaults.RegistrationBackend'. ```python REGISTRATION_BACKEND = 'organizations.backends.defaults.RegistrationBackend' ``` -------------------------------- ### Set Invitation Backend Source: https://github.com/bennylope/django-organizations/blob/master/docs/reference/settings.rst Specify the full dotted path to the custom invitation backend. Defaults to 'organizations.backends.defaults.InvitationBackend'. ```python INVITATION_BACKEND = 'organizations.backends.defaults.InvitationBackend' ``` -------------------------------- ### Custom Organization Model with Simple Inheritance Source: https://github.com/bennylope/django-organizations/blob/master/docs/cookbook.rst Demonstrates how to extend the base Organization model using multi-table inheritance to add custom fields like 'sport' and 'city'. ```python from django.db import models from organizations.models import Organization from sports.models import Sport class Team(Organization): sport = models.ForeignKey(Sport, related_name="teams") city = models.CharField(max_length=100) ``` -------------------------------- ### Configure URL Patterns for Django Organizations Source: https://github.com/bennylope/django-organizations/blob/master/README.rst Include the main application URL configuration and the invitation backend URLs in your project's URL patterns. This allows access to the library's views and invitation system. ```python from organizations.backends import invitation_backend urlpatterns = [ ... path('accounts/', include('organizations.urls')), path('invitations/', include(invitation_backend().get_urls())), ] ``` -------------------------------- ### Include Invitation Backend URLs Source: https://github.com/bennylope/django-organizations/blob/master/docs/custom_usage.rst Include the URL patterns provided by the invitation backend in your project's urls.py. This makes the invitation functionality accessible via URLs. ```python from organizations.backends import invitation_backend urlpatterns = [ ... url(r'^invite/', include(invitation_backend().get_urls())), ] ``` -------------------------------- ### Run Tests with Tox Source: https://github.com/bennylope/django-organizations/blob/master/CONTRIBUTING.rst Ensure your changes pass all tests across different Python versions using tox. ```bash tox ``` -------------------------------- ### Clone the Django Organizations Repository Source: https://github.com/bennylope/django-organizations/blob/master/CONTRIBUTING.rst Clone your forked repository locally to begin development. ```bash git clone git@github.com:your_name_here/django-organizations.git ``` -------------------------------- ### Configure INSTALLED_APPS for Django Organizations Source: https://github.com/bennylope/django-organizations/blob/master/README.rst Add 'organizations' to your INSTALLED_APPS to integrate the library into your Django project. Ensure 'django.contrib.auth' is also included. ```python INSTALLED_APPS = ( ... 'django.contrib.auth', 'organizations', ) ``` -------------------------------- ### Commit and Push Changes Source: https://github.com/bennylope/django-organizations/blob/master/CONTRIBUTING.rst Stage, commit, and push your changes to your GitHub fork. ```bash git add . git commit -m "Your detailed description of your changes." git push origin name-of-your-bugfix-or-feature ``` -------------------------------- ### Define Custom Organization Models using Abstract Classes Source: https://github.com/bennylope/django-organizations/blob/master/docs/cookbook.rst Inherit from abstract models to define custom organization, user, owner, and invitation models. Includes timestamps, slug, and is_admin fields. ```python from django.db import models from organizations.abstract import ( AbstractOrganization, AbstractOrganizationUser, AbstractOrganizationOwner, AbstractOrganizationInvitation, ) class Account(AbstractOrganization): """Core organization model""" monthly_subscription = models.IntegerField(default=1000) class AccountUser(AbstractOrganizationUser): """Links a user to the organization""" user_type = models.CharField(max_length=1, default='') class AccountOwner(AbstractOrganizationOwner): """Identifies ONE user, by AccountUser, to be the owner""" pass class AccountInvitation(AbstractOrganizationInvitation): """Stores invitations for adding users to organizations""" pass ``` -------------------------------- ### Create a New Branch for Development Source: https://github.com/bennylope/django-organizations/blob/master/CONTRIBUTING.rst Create a new branch for your bug fixes or feature implementations. ```bash git checkout -b name-of-your-bugfix-or-feature ``` -------------------------------- ### Configure URLs for Organizations Source: https://github.com/bennylope/django-organizations/blob/master/docs/getting_started.rst Include the organizations app URLs and optionally the invitation backend URLs in your project's urls.py. ```python from organizations.backends import invitation_backend urlpatterns = [ url(r'^accounts/', include('organizations.urls')), url(r'^invitations/', include(invitation_backend().get_urls())), ] ``` -------------------------------- ### Multiple Custom Organization Models with Inheritance Source: https://github.com/bennylope/django-organizations/blob/master/docs/cookbook.rst Illustrates extending the Organization model multiple times to create distinct organization types, such as 'Association' and 'Team', with their own fields and relationships. ```python from django.db import models from organizations.models import Organization from sports.models import Sport class Association(Organization): sport = models.ForeignKey(Sport, related_name="associations") class Team(Organization): association = models.ForeignKey(Association, related_name="teams") city = models.CharField(max_length=100) ``` -------------------------------- ### Custom Invitation Backend Source: https://github.com/bennylope/django-organizations/blob/master/docs/custom_usage.rst Extend the default InvitationBackend to handle user creation without a username, using email as the primary identifier. This is useful for custom user models. ```python from organizations.backends.defaults import InvitationBackend, make_random_password class CustomInvitations(InvitationBackend): def invite_by_email(self, email, sender=None, request=None, **kwargs): try: user = self.user_model.objects.get(email=email) except self.user_model.DoesNotExist: user = self.user_model.objects.create( email=email, password=make_random_password(), ) user.is_active = False user.save() self.send_invitation(user, sender, **kwargs) return user ``` -------------------------------- ### Configure INSTALLED_APPS Source: https://github.com/bennylope/django-organizations/blob/master/docs/getting_started.rst Add 'organizations' to your Django project's INSTALLED_APPS setting. ```python INSTALLED_APPS = ( 'django.contrib.auth', 'organizations', ) ``` -------------------------------- ### Specify Custom Invitation Backend Source: https://github.com/bennylope/django-organizations/blob/master/README.rst Define a custom invitation backend in your project settings if you need to override the default behavior. The `invitation_backend` function will then use the URLs defined by your custom backend. ```python INVITATION_BACKEND = 'myapp.backends.MyInvitationBackend' ``` -------------------------------- ### User Registration Form with Customizations Source: https://github.com/bennylope/django-organizations/blob/master/docs/cookbook.rst Extends the base UserRegistrationForm to include first name, last name, and password fields. Includes validation to ensure password entries match. ```python from django import forms from django.conf import settings from django.contrib.sites.models import Site from organizations.backends import invitation_backend from organizations.backends.forms import UserRegistrationForm from partners.models import PartnerUser class RegistrationForm(UserRegistrationForm): """ Form class that allows a user to register after clicking through an invitation. """ first_name = forms.CharField(max_length=30) last_name = forms.CharField(max_length=30) email = forms.EmailField(widget=forms.TextInput( attrs={'class': 'disabled', 'readonly': 'readonly'})) password = forms.CharField(max_length=128, widget=forms.PasswordInput) password_confirm = forms.CharField(max_length=128, widget=forms.PasswordInput) def clean(self): password = self.cleaned_data.get("password") password_confirm = self.cleaned_data.get("password_confirm") if password != password_confirm or not password: raise forms.ValidationError("Your password entries must match") return super(RegistrationForm, self).clean() ``` -------------------------------- ### Configure Custom Invitation Backend Source: https://github.com/bennylope/django-organizations/blob/master/docs/custom_usage.rst Specify your custom invitation backend in Django's settings.py. This tells Django Organizations which backend to use for invitations. ```python INVITATION_BACKEND = 'accounts.backends.CustomInvitations' ``` -------------------------------- ### Define Custom Organization Models using Base Classes Source: https://github.com/bennylope/django-organizations/blob/master/docs/cookbook.rst Inherit from base models for a minimalistic approach to defining custom organization, user, owner, and invitation models. Requires manual addition of fields like slugs or timestamps. ```python from django.db import models from organizations.base import ( OrganizationBase, OrganizationUserBase, OrganizationOwnerBase, OrganizationInvitationBase, ) class Account(OrganizationBase): monthly_subscription = models.IntegerField(default=1000) class AccountUser(OrganizationUserBase): user_type = models.CharField(max_length=1, default='') class AccountOwner(OrganizationOwnerBase): pass class AccountInvitation(OrganizationInvitationBase): pass ``` -------------------------------- ### Configuring Class-Based Views for Custom Organization Models Source: https://github.com/bennylope/django-organizations/blob/master/docs/cookbook.rst Shows how to configure class-based views to use a custom organization model (e.g., 'Team') by setting 'org_model' and 'org_context_name' attributes. ```python class TeamDetail(BaseOrganizationDetail): org_model = Team org_context_name = 'team' ``` -------------------------------- ### Simplifying Access Checks with Queryset Method Source: https://github.com/bennylope/django-organizations/blob/master/docs/usage.rst Create a custom queryset method to simplify filtering objects based on the user's organization membership. This method filters products accessible by a given user. ```python class ProductQuerySet(models.QuerySet): def for_user(self, user): return self.filter(account__users=user) ``` -------------------------------- ### Extend Organization Update View with Custom Context Source: https://github.com/bennylope/django-organizations/blob/master/docs/custom_usage.rst Create a view that inherits from a custom mixin and a base organization update view to add project-specific context data. ```python class AccountUpdateView(ServiceProviderOnly, BaseOrganizationUpdate): context_object_name = "account" template_name = "myapp/account_detail.html" def get_context_data(self, **kwargs): context = super(AccountUpdateView, self).get_context_data(**kwargs) context.update(provider=self.service_provider) return context ``` -------------------------------- ### Linking Resources with a Through Model Source: https://github.com/bennylope/django-organizations/blob/master/docs/cookbook.rst When linking to resources from third-party apps, create a linking model with a ForeignKey to both the Account and the external resource. Enforce uniqueness to prevent duplicate links. ```python from third_party_app.models import Document class DocumentLink(models.Model): account = models.ForeignKey('Account', related_name="document_links") document = models.ForeignKey('Document', unique=True) ``` -------------------------------- ### Custom Success URL for Invitation Backend Source: https://github.com/bennylope/django-organizations/blob/master/docs/reference/backends.rst Customize the success URL for the invitation backend by overriding the get_success_url method. By default, it redirects to the organization list URL. ```python def get_success_url(self): return reverse('my_fave_app') ``` -------------------------------- ### Define Proxy Models for Organizations Source: https://github.com/bennylope/django-organizations/blob/master/docs/cookbook.rst Use proxy models to customize organization and organization user models without altering the database schema. This allows for adding custom fields or behaviors. ```python from organizations.models import Organization, OrganizationUser class Account(Organization): class Meta: proxy = True class AccountUser(OrganizationUser): class Meta: proxy = True ``` -------------------------------- ### Create Custom View Mixin for Access Control Source: https://github.com/bennylope/django-organizations/blob/master/docs/custom_usage.rst Implement a custom mixin to enforce specific access control logic for organization-related views, such as restricting access to admins or members of a service provider. ```python class ServiceProvidersOnly(LoginRequired, OrganizationMixin): def dispatch(self, request, *args, **kwargs): self.request = request self.args = args self.kwargs = kwargs self.organization = self.get_organization() self.service_provider = self.organization.provider if not self.organization.is_admin(request.user) and not \ self.service_provider.is_member(request.user): raise PermissionDenied(_("Sorry, admins only")) return super(AdminRequiredMixin, self).dispatch(request, *args, **kwargs) ``` -------------------------------- ### Extend Base Admin Classes for Organizations Source: https://github.com/bennylope/django-organizations/blob/master/docs/cookbook.rst Reuse base admin classes to reduce boilerplate code when managing custom organization models. Includes inline owner management and registration for organization and user models. ```python from django.contrib import admin from organizations.base_admin import ( BaseOwnerInline, BaseOrganizationAdmin, BaseOrganizationUserAdmin, BaseOrganizationOwnerAdmin, ) from myapp.models import MyOrg, MyOrgUser, MyOrgOwner, MyOrgInvitation class OwnerInline(BaseOwnerInline): model = MyOrgOwner @admin.register(MyOrg) class OrgAdmin(BaseOrganizationAdmin): inlines = [OwnerInline] @admin.register(MyOrgUser) class OrgUserAdmin(BaseOrganizationUserAdmin): pass @admin.register(MyOrgOwner) class OrgOwnerAdmin(BaseOrganizationOwnerAdmin): pass @admin.register(MyOrgInvitation) class OrgInvitationAdmin(admin.ModelAdmin): pass ``` -------------------------------- ### Create Custom Admin Form for Organization Users Source: https://github.com/bennylope/django-organizations/blob/master/docs/cookbook.rst Develop a custom ModelForm to handle both organization user details and linked user model information. This form allows editing of first name, last name, and email, and handles user creation or updates. ```python from django import forms from django.conf import settings from django.contrib.sites.models import Site from organizations.backends import invitation_backend from myapp.models import AccountUser class AccountUserForm(forms.ModelForm): """ Form class for editing OrganizationUsers *and* the linked user model. """ first_name = forms.CharField(max_length=100) last_name = forms.CharField(max_length=100) email = forms.EmailField() class Meta: exclude = ('user', 'is_admin') model = AccountUser def __init__(self, *args, **kwargs): super(AccountUserForm, self).__init__(*args, **kwargs) if self.instance.pk is not None: self.fields['first_name'].initial = self.instance.user.first_name self.fields['last_name'].initial = self.instance.user.last_name self.fields['email'].initial = self.instance.user.email def save(self, *args, **kwargs): """ This method saves changes to the linked user model. """ if self.instance.pk is None: site = Site.objects.get(pk=settings.SITE_ID) self.instance.user = invitation_backend().invite_by_email( self.cleaned_data['email'], **{'first_name': self.cleaned_data['first_name'], 'last_name': self.cleaned_data['last_name'], 'organization': self.cleaned_data['organization'], 'domain': site}) self.instance.user.first_name = self.cleaned_data['first_name'] self.instance.user.last_name = self.cleaned_data['last_name'] ``` -------------------------------- ### Define Custom Organization Models Source: https://github.com/bennylope/django-organizations/blob/master/docs/custom_usage.rst Extend the base Organization model to add custom fields and relationships for specific organizational structures like service providers and clients. ```python class ServiceProvider(Organization): """Now this model has a name field and a slug field""" url = models.URLField() class Client(Organization): """Now this model has a name field and a slug field""" service_provider = models.ForeignKey(ServiceProvider, related_name="clients") subscription_plan = models.ForeignKey(SubscriptionPlan) subscription_start = models.DateField() url = models.URLField() description = models.TextField() objects = models.Manager() ``` -------------------------------- ### Restricting Document Access with Custom Manager Method Source: https://github.com/bennylope/django-organizations/blob/master/docs/cookbook.rst Encapsulate access restriction logic within a custom manager method (e.g., `for_user`) for improved clarity and reusability. This method should reduce the queryset to only relevant documents for the current user. ```python @login_required def document_view(request, document_pk): try: doc = Document.objects.for_user(request.user).get(pk=document_pk) except Document.DoesNotExist: raise Http404 return render(request, "document.html", {"document": doc}) ``` -------------------------------- ### Define View Mixin Explicitly Source: https://github.com/bennylope/django-organizations/blob/master/docs/custom_usage.rst Define a view mixin without inheriting from a base class, demonstrating an alternative approach for explicit mixin definitions. ```python class ServiceProvidersOnly(object): def dispatch(self, request, *args, **kwargs): self.request = request self.args = args self.kwargs = kwargs self.organization = self.get_organization() self.service_provider = self.organization.provider if not self.organization.is_admin(request.user) and not \ self.service_provider.is_member(request.user): ``` -------------------------------- ### Accessing Related Resources with ForeignKey Source: https://github.com/bennylope/django-organizations/blob/master/docs/cookbook.rst Use the related name on a ForeignKey to access resources linked to an account. Ensure the resource model is defined within your project. ```python account = get_object_or_404(Account, pk=pk) relevant_meeting_minutes = account.meeting_minutes.all() ``` -------------------------------- ### Configure Custom User Model Source: https://github.com/bennylope/django-organizations/blob/master/docs/custom_usage.rst Specify a custom user model in Django's settings to be used by django-organizations. ```python AUTH_USER_MODEL = 'auth.User' ``` ```python AUTH_USER_MODEL = 'myapp.MyUser' ``` -------------------------------- ### OrgManager.get_for_user Source: https://github.com/bennylope/django-organizations/blob/master/docs/reference/managers.rst Retrieves a QuerySet of all Organizations that a given user is a member of. ```APIDOC ## OrgManager.get_for_user(user) ### Description Returns a QuerySet of Organizations that the given user is a member of. ### Parameters #### Path Parameters - **user** (User object) - Required - The user object for whom to retrieve organizations. ``` -------------------------------- ### Relating Models to Organizations Source: https://github.com/bennylope/django-organizations/blob/master/docs/usage.rst Tie other objects to an organization by using a ForeignKey to the Organization model. Ensure your organization models are at the top of your app hierarchy. ```python class Product(models.Model): account = models.ForeignKey( 'organizations.Organization', related_name='products', ) ``` -------------------------------- ### Set Auth User Model Source: https://github.com/bennylope/django-organizations/blob/master/docs/reference/settings.rst Define the swappable user model for Django 1.5+ or to relate a custom user model in Django 1.4. Defaults to 'auth.User'. ```python AUTH_USER_MODEL = 'auth.User' ``` -------------------------------- ### Using Organization Template Tags Source: https://github.com/bennylope/django-organizations/blob/master/docs/usage.rst Leverage built-in template tags to check user roles within an organization. Load the tags and use `is_admin` or `is_owner` filters with `organization` and `user` context variables. ```django {% load org_tags %} {# somewhere in your template you have `organization` and `user` variable #} {% if organization|is_admin:user %} {{ user }} is a administrator of the {{ organization.name }} organization. {% elif organization|is_owner:user %} {{ user }} is owner of the {{ organization.name }} organization. {% endif %} ``` -------------------------------- ### Restricting Document Access with User Filter Source: https://github.com/bennylope/django-organizations/blob/master/docs/cookbook.rst In a view, restrict access to a specific document by filtering against the user's membership in an account. This is a concise way to enforce access control. ```python @login_required def document_view(request, document_pk): doc = get_object_or_404(Document, pk=document_pk, account__users=request.user) return render(request, "document.html", {"document": doc}) ``` -------------------------------- ### Configure Admin Interface for Organizations Source: https://github.com/bennylope/django-organizations/blob/master/docs/cookbook.rst Customize the Django admin interface to manage organizations and their users. This involves unregistering default models and registering custom ones with specific forms. ```python from django.contrib import admin from organizations.models import ( Organization, OrganizationUser, OrganizationOwner) from myapp.forms import AccountUserForm from myapp.models import Account, AccountUser class AccountUserAdmin(admin.ModelAdmin): form = AccountUserForm admin.site.unregister(Organization) admin.site.unregister(OrganizationUser) admin.site.unregister(OrganizationOwner) admin.site.register(Account) admin.site.register(AccountUser, AccountUserAdmin) ``` -------------------------------- ### Specify Custom AutoSlugField Source: https://github.com/bennylope/django-organizations/blob/master/docs/getting_started.rst If using default models, you can specify a different AutoSlugField source. ```python ORGS_SLUGFIELD = 'django_extensions.db.fields.AutoSlugField' ``` -------------------------------- ### Defining ManyToManyField with a Through Model Source: https://github.com/bennylope/django-organizations/blob/master/docs/cookbook.rst Define a ManyToManyField with a custom 'through' model to manage relationships between accounts and external resources, providing a cleaner interface. ```python class Account(Organization): documents = models.ManyToManyField('third_party_app.Document', through='DocumentLink') ``` -------------------------------- ### Configure Auto Slug Field for Organizations Source: https://github.com/bennylope/django-organizations/blob/master/README.rst Specify the auto slug field to be used by Django Organizations. The default is 'django_extensions.db.fields.AutoSlugField', but you can configure an alternative like 'autoslug.fields.AutoSlugField'. ```python ORGS_SLUGFIELD = 'django_extensions.db.fields.AutoSlugField' ``` ```python ORGS_SLUGFIELD = 'autoslug.fields.AutoSlugField' ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.