The Django-Access-Select2 package provides a filtering for the Django-Select2 package to use access rules defined by the Django-Access package.
Stable version from the PyPi package repository
pip install django-access-select2Last development version from the GitHub source version control system
pip install git+git://github.com/nnseva/django-access-select2.gitInclude the django_select2, access, and access_select2 applications into the INSTALLED_APPS list, like:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
...
'django_select2',
'access',
'access_select2',
...
]Remove if present, the existent reference to the Django-Select2 urlconf from your urlconfs and insert the modified one from the package:
# url(r'^select2/', include('django_select2.urls')), -- removed
url(r'^select2/', include('access_select2.urls')), # -- modifiedDefine access rules as it is described in the Django-Access package documentation.
Note that the Django-Access-Select2 package uses only apply_visible AccessManager method to filter, what the user can see in the dropdown list of objects.
Remove if preset, the existent reference to the widget, and use the modified one
# from django_select2.forms import ModelSelect2Widget, ModelSelect2MultipleWidget, ModelSelect2TagWidget -- removed
from access_select2.forms import ModelSelect2Widget, ModelSelect2MultipleWidget, ModelSelect2TagWidget # -- modifiedNote that the select2.js library requires jQuery media, but Django-Select2 package doesn't refer it.
Sometimes it leads to broken functional of the Django-Select2 package, for instance on the admin page by default. You may use
any tool to include the jQuery media into your pages. For instance, you can use a special Media class in your Admin classes,
or forms using Django-Select2 widgets, like this:
class SomeObjectAdmin(ModelAdmin):
...
class Media:
js = ['//code.jquery.com/jquery-2.2.4.js']
The AutoResponseView class is slightly modified by the package: the get_queryset method now takes the positional request parameter.
If you are using AutoResponseView class directly in your code, yu should replace reference to it to the modified one and modify the
get_queryset method prototype:
# from django_select2.views import AutoResponseView -- removed
from access_select2.views import AutoResponseView # -- modified
class MyAutoResponseView(AutoResponseView):
...
# def get_queryset(self): -- removed
def get_queryset(self, request): # -- modified
...Having in mind the example defined for the Django-Access, let we use the the package as the following:
from django.contrib import admin
from access.admin import *
from access_select2.forms import ModelSelect2Widget, ModelSelect2MultipleWidget, ModelSelect2TagWidget # -- modified
from someapp.models import *
class ChildAdmin(AccessTabularInline):
model = SomeChild
# Register your models here.
class ObjectAdmin(AccessModelAdmin):
inlines = [
ChildAdmin,
]
related_search_fields = {
'editor_group': ('name__startswith',),
'viewer_groups': ('name__startswith',),
}
def formfield_for_dbfield(self, db_field, **kwargs):
"""
Overrides the default widget for Foreignkey fields if they are
specified in the select_search_fields class attribute.
"""
kw = {}
kw.update(kwargs)
if isinstance(db_field, models.ForeignKey) and hasattr(self, 'related_search_fields') \
and db_field.name in self.related_search_fields:
kw['widget'] = ModelSelect2Widget(model=db_field.target_field.model,search_fields=self.related_search_fields[db_field.name])
elif isinstance(db_field, models.ManyToManyField) and hasattr(self, 'related_search_fields') \
and db_field.name in self.related_search_fields:
kw['widget'] = ModelSelect2MultipleWidget(model=db_field.target_field.model,search_fields=self.related_search_fields[db_field.name])
return super(ObjectAdmin, self).formfield_for_dbfield(db_field, **kw)
class Media:
js = ['//code.jquery.com/jquery-2.2.4.js']
# Register your models here.
admin.site.register(SomeObject,ObjectAdmin)