diff --git a/mayan/apps/appearance/templates/appearance/base.html b/mayan/apps/appearance/templates/appearance/base.html
index 2e5771dc34..b3b2ffdff0 100644
--- a/mayan/apps/appearance/templates/appearance/base.html
+++ b/mayan/apps/appearance/templates/appearance/base.html
@@ -70,7 +70,7 @@
{% if not user.is_authenticated %}
{% trans 'Anonymous' %}
{% else %}
-
{{ user.get_full_name|default:user }}
+ {{ request.organization }}: {{ user.get_full_name|default:user }}
{% endif %}
diff --git a/mayan/apps/documents/forms.py b/mayan/apps/documents/forms.py
index ad7808fd86..f2237e4b69 100644
--- a/mayan/apps/documents/forms.py
+++ b/mayan/apps/documents/forms.py
@@ -104,7 +104,7 @@ class DocumentTypeSelectForm(forms.Form):
as form #1 in the document creation wizard
"""
document_type = forms.ModelChoiceField(
- queryset=DocumentType.objects.all(), label=_('Document type')
+ queryset=DocumentType.on_organization.all(), label=_('Document type')
)
diff --git a/mayan/apps/documents/managers.py b/mayan/apps/documents/managers.py
index 6dba4b61d1..68438270c2 100644
--- a/mayan/apps/documents/managers.py
+++ b/mayan/apps/documents/managers.py
@@ -4,6 +4,7 @@ from datetime import timedelta
import logging
from django.apps import apps
+from django.conf import settings
from django.db import models
from django.utils.timezone import now
@@ -132,7 +133,8 @@ class RecentDocumentManager(models.Manager):
if user.is_authenticated():
return document_model.objects.filter(
- recentdocument__user=user
+ recentdocument__user=user,
+ document_type__organization__id=settings.ORGANIZATION_ID
).order_by('-recentdocument__datetime_accessed')
else:
return document_model.objects.none()
diff --git a/mayan/apps/documents/migrations/0029_documenttype_organization.py b/mayan/apps/documents/migrations/0029_documenttype_organization.py
new file mode 100644
index 0000000000..bf0504e52f
--- /dev/null
+++ b/mayan/apps/documents/migrations/0029_documenttype_organization.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('organizations', '0001_initial'),
+ ('documents', '0028_newversionblock'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='documenttype',
+ name='organization',
+ field=models.ForeignKey(default=1, to='organizations.Organization'),
+ preserve_default=False,
+ ),
+ ]
diff --git a/mayan/apps/documents/migrations/0030_document_organization.py b/mayan/apps/documents/migrations/0030_document_organization.py
new file mode 100644
index 0000000000..d24344498f
--- /dev/null
+++ b/mayan/apps/documents/migrations/0030_document_organization.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('organizations', '0001_initial'),
+ ('documents', '0029_documenttype_organization'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='document',
+ name='organization',
+ field=models.ForeignKey(default=1, to='organizations.Organization'),
+ preserve_default=False,
+ ),
+ ]
diff --git a/mayan/apps/documents/migrations/0031_remove_document_organization.py b/mayan/apps/documents/migrations/0031_remove_document_organization.py
new file mode 100644
index 0000000000..ddafccbcb9
--- /dev/null
+++ b/mayan/apps/documents/migrations/0031_remove_document_organization.py
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('documents', '0030_document_organization'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='document',
+ name='organization',
+ ),
+ ]
diff --git a/mayan/apps/documents/migrations/0032_auto_20160307_0504.py b/mayan/apps/documents/migrations/0032_auto_20160307_0504.py
new file mode 100644
index 0000000000..ec74666d13
--- /dev/null
+++ b/mayan/apps/documents/migrations/0032_auto_20160307_0504.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+import organizations.shortcuts
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('documents', '0031_remove_document_organization'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='documenttype',
+ name='organization',
+ field=models.ForeignKey(default=organizations.shortcuts.get_current_organization, to='organizations.Organization'),
+ preserve_default=True,
+ ),
+ ]
diff --git a/mayan/apps/documents/models.py b/mayan/apps/documents/models.py
index c671b0d733..0142628e36 100644
--- a/mayan/apps/documents/models.py
+++ b/mayan/apps/documents/models.py
@@ -24,6 +24,9 @@ from converter.exceptions import InvalidOfficeFormat, PageCountError
from converter.literals import DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION
from converter.models import Transformation
from mimetype.api import get_mimetype
+from organizations.models import Organization
+from organizations.managers import CurrentOrganizationManager
+from organizations.shortcuts import get_current_organization
from permissions import Permission
from .events import (
@@ -62,6 +65,9 @@ class DocumentType(models.Model):
Define document types or classes to which a specific set of
properties can be attached
"""
+ organization = models.ForeignKey(
+ Organization, default=get_current_organization
+ )
label = models.CharField(
max_length=32, unique=True, verbose_name=_('Label')
)
@@ -87,6 +93,7 @@ class DocumentType(models.Model):
)
objects = DocumentTypeManager()
+ on_organization = CurrentOrganizationManager()
def __str__(self):
return self.label
diff --git a/mayan/apps/documents/views.py b/mayan/apps/documents/views.py
index 4ee92bbddb..27d31d8a73 100644
--- a/mayan/apps/documents/views.py
+++ b/mayan/apps/documents/views.py
@@ -72,7 +72,7 @@ class DocumentListView(SingleObjectListView):
object_permission = permission_document_view
def get_document_queryset(self):
- return Document.objects.all()
+ return Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID)
def get_queryset(self):
self.queryset = self.get_document_queryset().filter(is_stub=False)
@@ -88,7 +88,7 @@ class DeletedDocumentListView(DocumentListView):
}
def get_document_queryset(self):
- queryset = Document.trash.all()
+ queryset = Document.trash.filter(document_type__organization__id=settings.ORGANIZATION_ID)
try:
Permission.check_permissions(
@@ -111,7 +111,7 @@ class DeletedDocumentDeleteView(ConfirmView):
def object_action(self, instance):
source_document = get_object_or_404(
- Document.passthrough, pk=instance.pk
+ Document.passthrough.filter(document_type__organization__id=settings.ORGANIZATION_ID), pk=instance.pk
)
try:
@@ -139,14 +139,15 @@ class DeletedDocumentDeleteManyView(MultipleInstanceActionMixin, DeletedDocument
extra_context = {
'title': _('Delete the selected documents?')
}
- model = DeletedDocument
success_message = '%(count)d document deleted.'
success_message_plural = '%(count)d documents deleted.'
+ def get_queryset(self):
+ return DeletedDocument.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID)
+
class DocumentEditView(SingleObjectEditView):
form_class = DocumentForm
- model = Document
object_permission = permission_document_properties_edit
def dispatch(self, request, *args, **kwargs):
@@ -162,16 +163,19 @@ class DocumentEditView(SingleObjectEditView):
'title': _('Edit properties of document: %s') % self.get_object(),
}
- def get_save_extra_data(self):
- return {
- '_user': self.request.user
- }
+ def get_queryset(self):
+ return Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID)
def get_post_action_redirect(self):
return reverse(
'documents:document_properties', args=(self.get_object().pk,)
)
+ def get_save_extra_data(self):
+ return {
+ '_user': self.request.user
+ }
+
class DocumentRestoreView(ConfirmView):
extra_context = {
@@ -180,7 +184,7 @@ class DocumentRestoreView(ConfirmView):
def object_action(self, instance):
source_document = get_object_or_404(
- Document.passthrough, pk=instance.pk
+ Document.passthrough.filter(document_type__organization__id=settings.ORGANIZATION_ID), pk=instance.pk
)
try:
@@ -210,10 +214,12 @@ class DocumentRestoreManyView(MultipleInstanceActionMixin, DocumentRestoreView):
extra_context = {
'title': _('Restore the selected documents?')
}
- model = DeletedDocument
success_message = '%(count)d document restored.'
success_message_plural = '%(count)d documents restored.'
+ def get_queryset(self):
+ return DeletedDocument.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID)
+
class DocumentPageListView(SingleObjectListView):
def dispatch(self, request, *args, **kwargs):
@@ -232,7 +238,7 @@ class DocumentPageListView(SingleObjectListView):
).dispatch(request, *args, **kwargs)
def get_document(self):
- return get_object_or_404(Document, pk=self.kwargs['pk'])
+ return get_object_or_404(Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID), pk=self.kwargs['pk'])
def get_queryset(self):
return self.get_document().pages.all()
@@ -287,11 +293,10 @@ class DocumentPageView(SimpleView):
}
def get_object(self):
- return get_object_or_404(DocumentPage, pk=self.kwargs['pk'])
+ return get_object_or_404(DocumentPage.objects.filter(document__document_type__organization__pk=settings.ORGANIZATION_ID), pk=self.kwargs['pk'])
class DocumentPreviewView(SingleObjectDetailView):
- model = Document
object_permission = permission_document_view
def dispatch(self, request, *args, **kwargs):
@@ -309,6 +314,9 @@ class DocumentPreviewView(SingleObjectDetailView):
'title': _('Preview of document: %s') % self.get_object(),
}
+ def get_queryset(self):
+ return Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID)
+
class DocumentTrashView(ConfirmView):
def get_extra_context(self):
@@ -318,7 +326,7 @@ class DocumentTrashView(ConfirmView):
}
def get_object(self):
- return get_object_or_404(Document, pk=self.kwargs['pk'])
+ return get_object_or_404(Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID), pk=self.kwargs['pk'])
def get_post_action_redirect(self):
return reverse('documents:document_list_recent')
@@ -348,7 +356,6 @@ class DocumentTrashView(ConfirmView):
class DocumentTrashManyView(MultipleInstanceActionMixin, DocumentTrashView):
- model = Document
success_message = '%(count)d document moved to the trash.'
success_message_plural = '%(count)d documents moved to the trash.'
@@ -357,10 +364,13 @@ class DocumentTrashManyView(MultipleInstanceActionMixin, DocumentTrashView):
'title': _('Move the selected documents to the trash?')
}
+ def get_queryset(self):
+ return Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID)
+
class DocumentTypeDocumentListView(DocumentListView):
def get_document_type(self):
- return get_object_or_404(DocumentType, pk=self.kwargs['pk'])
+ return get_object_or_404(DocumentType.objects.filter(organization__id=settings.ORGANIZATION_ID), pk=self.kwargs['pk'])
def get_document_queryset(self):
return self.get_document_type().documents.all()
@@ -374,7 +384,6 @@ class DocumentTypeDocumentListView(DocumentListView):
class DocumentTypeListView(SingleObjectListView):
- model = DocumentType
view_permission = permission_document_type_view
def get_extra_context(self):
@@ -383,13 +392,15 @@ class DocumentTypeListView(SingleObjectListView):
'title': _('Document types'),
}
+ def get_queryset(self):
+ return DocumentType.objects.filter(organization__id=settings.ORGANIZATION_ID)
+
class DocumentTypeCreateView(SingleObjectCreateView):
fields = (
'label', 'trash_time_period', 'trash_time_unit', 'delete_time_period',
'delete_time_unit'
)
- model = DocumentType
post_action_redirect = reverse_lazy('documents:document_type_list')
view_permission = permission_document_type_create
@@ -398,9 +409,11 @@ class DocumentTypeCreateView(SingleObjectCreateView):
'title': _('Create document type'),
}
+ def get_queryset(self):
+ return DocumentType.objects.filter(organization__id=settings.ORGANIZATION_ID)
+
class DocumentTypeDeleteView(SingleObjectDeleteView):
- model = DocumentType
post_action_redirect = reverse_lazy('documents:document_type_list')
view_permission = permission_document_type_delete
@@ -411,13 +424,15 @@ class DocumentTypeDeleteView(SingleObjectDeleteView):
'title': _('Delete the document type: %s?') % self.get_object(),
}
+ def get_queryset(self):
+ return DocumentType.objects.filter(organization__id=settings.ORGANIZATION_ID)
+
class DocumentTypeEditView(SingleObjectEditView):
fields = (
'label', 'trash_time_period', 'trash_time_unit', 'delete_time_period',
'delete_time_unit'
)
- model = DocumentType
post_action_redirect = reverse_lazy('documents:document_type_list')
view_permission = permission_document_type_edit
@@ -427,13 +442,15 @@ class DocumentTypeEditView(SingleObjectEditView):
'title': _('Edit document type: %s') % self.get_object(),
}
+ def get_queryset(self):
+ return DocumentType.objects.filter(organization__id=settings.ORGANIZATION_ID)
+
class DocumentTypeFilenameListView(SingleObjectListView):
- model = DocumentType
view_permission = permission_document_type_view
def get_document_type(self):
- return get_object_or_404(DocumentType, pk=self.kwargs['pk'])
+ return get_object_or_404(DocumentType.objects.filter(organization__id=settings.ORGANIZATION_ID), pk=self.kwargs['pk'])
def get_extra_context(self):
return {
@@ -451,7 +468,6 @@ class DocumentTypeFilenameListView(SingleObjectListView):
class DocumentTypeFilenameEditView(SingleObjectEditView):
fields = ('enabled', 'filename',)
- model = DocumentTypeFilename
view_permission = permission_document_type_edit
def get_extra_context(self):
@@ -476,9 +492,11 @@ class DocumentTypeFilenameEditView(SingleObjectEditView):
args=(self.get_object().document_type.pk,)
)
+ def get_queryset(self):
+ return DocumentTypeFilename.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID)
+
class DocumentTypeFilenameDeleteView(SingleObjectDeleteView):
- model = DocumentTypeFilename
view_permission = permission_document_type_edit
def get_extra_context(self):
@@ -501,6 +519,9 @@ class DocumentTypeFilenameDeleteView(SingleObjectDeleteView):
args=(self.get_object().document_type.pk,)
)
+ def get_queryset(self):
+ return DocumentTypeFilename.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID)
+
class DocumentVersionListView(SingleObjectListView):
def dispatch(self, request, *args, **kwargs):
@@ -520,7 +541,7 @@ class DocumentVersionListView(SingleObjectListView):
).dispatch(request, *args, **kwargs)
def get_document(self):
- return get_object_or_404(Document, pk=self.kwargs['pk'])
+ return get_object_or_404(Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID), pk=self.kwargs['pk'])
def get_extra_context(self):
return {
@@ -533,7 +554,6 @@ class DocumentVersionListView(SingleObjectListView):
class DocumentView(SingleObjectDetailView):
- model = Document
object_permission = permission_document_view
def dispatch(self, request, *args, **kwargs):
@@ -592,6 +612,9 @@ class DocumentView(SingleObjectDetailView):
instance=document, extra_fields=document_fields
)
+ def get_queryset(self):
+ return Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID)
+
class EmptyTrashCanView(ConfirmView):
extra_context = {
@@ -603,7 +626,7 @@ class EmptyTrashCanView(ConfirmView):
)
def view_action(self):
- for deleted_document in DeletedDocument.objects.all():
+ for deleted_document in DeletedDocument.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID):
deleted_document.delete()
messages.success(self.request, _('Trash emptied successfully'))
@@ -622,11 +645,13 @@ class RecentDocumentListView(DocumentListView):
def document_document_type_edit(request, document_id=None, document_id_list=None):
post_action_redirect = None
+ queryset = Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID)
+
if document_id:
- queryset = Document.objects.filter(pk=document_id)
+ queryset = queryset.filter(pk=document_id)
post_action_redirect = reverse('documents:document_list_recent')
elif document_id_list:
- queryset = Document.objects.filter(pk__in=document_id_list)
+ queryset = queryset.filter(pk__in=document_id_list)
try:
Permission.check_permissions(
@@ -700,7 +725,7 @@ def document_multiple_document_type_edit(request):
# TODO: Get rid of this view and convert widget to use API and base64 only images
def get_document_image(request, document_id, size=setting_preview_size.value):
- document = get_object_or_404(Document.passthrough, pk=document_id)
+ document = get_object_or_404(Document.passthrough.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID), pk=document_id)
try:
Permission.check_permissions(request.user, (permission_document_view,))
except PermissionDenied:
@@ -732,12 +757,14 @@ def get_document_image(request, document_id, size=setting_preview_size.value):
def document_download(request, document_id=None, document_id_list=None, document_version_pk=None):
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL))))
+ queryset = Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID)
+
if document_id:
- documents = Document.objects.filter(pk=document_id)
+ documents = queryset.filter(pk=document_id)
elif document_id_list:
- documents = Document.objects.filter(pk__in=document_id_list)
+ documents = queryset.filter(pk__in=document_id_list)
elif document_version_pk:
- documents = Document.objects.filter(
+ documents = queryset.filter(
pk=get_object_or_404(
DocumentVersion, pk=document_version_pk
).document.pk
@@ -762,6 +789,7 @@ def document_download(request, document_id=None, document_id_list=None, document
)
)
+ # TODO: check organization
if document_version_pk:
queryset = DocumentVersion.objects.filter(pk=document_version_pk)
else:
@@ -873,10 +901,12 @@ def document_multiple_download(request):
def document_update_page_count(request, document_id=None, document_id_list=None):
+ queryset = Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID)
+
if document_id:
- documents = Document.objects.filter(pk=document_id)
+ documents = queryset.filter(pk=document_id)
elif document_id_list:
- documents = Document.objects.filter(pk__in=document_id_list)
+ documents = queryset.objects.filter(pk__in=document_id_list)
if not documents:
messages.error(request, _('At least one document must be selected.'))
@@ -936,11 +966,13 @@ def document_multiple_update_page_count(request):
def document_clear_transformations(request, document_id=None, document_id_list=None):
+ queryset = Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID)
+
if document_id:
- documents = Document.objects.filter(pk=document_id)
+ documents = queryset.filter(pk=document_id)
post_redirect = documents[0].get_absolute_url()
elif document_id_list:
- documents = Document.objects.filter(pk__in=document_id_list)
+ documents = queryset.filter(pk__in=document_id_list)
post_redirect = None
if not documents:
@@ -1020,7 +1052,7 @@ def document_page_view_reset(request, document_page_id):
def document_page_navigation_next(request, document_page_id):
- document_page = get_object_or_404(DocumentPage, pk=document_page_id)
+ document_page = get_object_or_404(DocumentPage.objects.filter(document__document_type__organization__id=settings.ORGANIZATION_ID), pk=document_page_id)
try:
Permission.check_permissions(request.user, (permission_document_view,))
@@ -1038,7 +1070,7 @@ def document_page_navigation_next(request, document_page_id):
def document_page_navigation_previous(request, document_page_id):
- document_page = get_object_or_404(DocumentPage, pk=document_page_id)
+ document_page = get_object_or_404(DocumentPage.objects.filter(document__document_type__organization__id=settings.ORGANIZATION_ID), pk=document_page_id)
try:
Permission.check_permissions(request.user, (permission_document_view,))
@@ -1056,7 +1088,7 @@ def document_page_navigation_previous(request, document_page_id):
def document_page_navigation_first(request, document_page_id):
- document_page = get_object_or_404(DocumentPage, pk=document_page_id)
+ document_page = get_object_or_404(DocumentPage.objects.filter(document__document_type__organization__id=settings.ORGANIZATION_ID), pk=document_page_id)
document_page = get_object_or_404(document_page.siblings, page_number=1)
try:
@@ -1070,7 +1102,7 @@ def document_page_navigation_first(request, document_page_id):
def document_page_navigation_last(request, document_page_id):
- document_page = get_object_or_404(DocumentPage, pk=document_page_id)
+ document_page = get_object_or_404(DocumentPage.objects.filter(document__document_type__organization__id=settings.ORGANIZATION_ID), pk=document_page_id)
document_page = get_object_or_404(document_page.siblings, page_number=document_page.siblings.count())
try:
@@ -1084,7 +1116,7 @@ def document_page_navigation_last(request, document_page_id):
def transform_page(request, document_page_id, zoom_function=None, rotation_function=None):
- document_page = get_object_or_404(DocumentPage, pk=document_page_id)
+ document_page = get_object_or_404(DocumentPage.objects.filter(document__document_type__organization__id=settings.ORGANIZATION_ID), pk=document_page_id)
try:
Permission.check_permissions(request.user, (permission_document_view,))
@@ -1147,7 +1179,7 @@ def document_page_rotate_left(request, document_page_id):
def document_print(request, document_id):
- document = get_object_or_404(Document, pk=document_id)
+ document = get_object_or_404(Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID), pk=document_id)
try:
Permission.check_permissions(request.user, (permission_document_print,))
@@ -1194,7 +1226,7 @@ def document_print(request, document_id):
def document_type_filename_create(request, document_type_id):
Permission.check_permissions(request.user, (permission_document_type_edit,))
- document_type = get_object_or_404(DocumentType, pk=document_type_id)
+ document_type = get_object_or_404(DocumentType.objects.filter(organization__id=settings.ORGANIZATION_ID), pk=document_type_id)
if request.method == 'POST':
form = DocumentTypeFilenameForm_create(request.POST)
@@ -1240,7 +1272,7 @@ def document_clear_image_cache(request):
def document_version_revert(request, document_version_pk):
- document_version = get_object_or_404(DocumentVersion, pk=document_version_pk)
+ document_version = get_object_or_404(DocumentVersion.objects.filter(document__document_type__organization__id=settings.ORGANIZATION_ID), pk=document_version_pk)
try:
Permission.check_permissions(request.user, (permission_document_version_revert,))
diff --git a/mayan/apps/folders/forms.py b/mayan/apps/folders/forms.py
index e0a4b991c7..c1cc6fda1f 100644
--- a/mayan/apps/folders/forms.py
+++ b/mayan/apps/folders/forms.py
@@ -21,7 +21,7 @@ class FolderListForm(forms.Form):
logger.debug('user: %s', user)
super(FolderListForm, self).__init__(*args, **kwargs)
- queryset = Folder.objects.all()
+ queryset = Folder.on_organization.all()
try:
Permission.check_permissions(user, (permission_folder_view,))
except PermissionDenied:
diff --git a/mayan/apps/folders/migrations/0005_folder_organization.py b/mayan/apps/folders/migrations/0005_folder_organization.py
new file mode 100644
index 0000000000..4715175d72
--- /dev/null
+++ b/mayan/apps/folders/migrations/0005_folder_organization.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+import organizations.shortcuts
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('organizations', '0001_initial'),
+ ('folders', '0004_documentfolder'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='folder',
+ name='organization',
+ field=models.ForeignKey(default=organizations.shortcuts.get_current_organization, to='organizations.Organization'),
+ preserve_default=True,
+ ),
+ ]
diff --git a/mayan/apps/folders/models.py b/mayan/apps/folders/models.py
index a5e2a83d58..4db0235042 100644
--- a/mayan/apps/folders/models.py
+++ b/mayan/apps/folders/models.py
@@ -10,6 +10,9 @@ from django.utils.translation import ugettext_lazy as _
from acls.models import AccessControlList
from documents.models import Document
from documents.permissions import permission_document_view
+from organizations.models import Organization
+from organizations.managers import CurrentOrganizationManager
+from organizations.shortcuts import get_current_organization
from permissions import Permission
from .managers import FolderManager
@@ -17,6 +20,9 @@ from .managers import FolderManager
@python_2_unicode_compatible
class Folder(models.Model):
+ organization = models.ForeignKey(
+ Organization, default=get_current_organization
+ )
label = models.CharField(
db_index=True, max_length=128, verbose_name=_('Label')
)
@@ -29,6 +35,7 @@ class Folder(models.Model):
)
objects = FolderManager()
+ on_organization = CurrentOrganizationManager()
def __str__(self):
return self.label
diff --git a/mayan/apps/folders/views.py b/mayan/apps/folders/views.py
index 796fe8d6d1..81f84d65aa 100644
--- a/mayan/apps/folders/views.py
+++ b/mayan/apps/folders/views.py
@@ -33,7 +33,6 @@ logger = logging.getLogger(__name__)
class FolderEditView(SingleObjectEditView):
fields = ('label',)
- model = Folder
object_permission = permission_folder_edit
post_action_redirect = reverse_lazy('folders:folder_list')
@@ -43,6 +42,9 @@ class FolderEditView(SingleObjectEditView):
'title': _('Edit folder: %s') % self.get_object(),
}
+ def get_document_queryset(self):
+ return Folder.on_organization.all()
+
class FolderListView(SingleObjectListView):
object_permission = permission_folder_view
@@ -54,7 +56,7 @@ class FolderListView(SingleObjectListView):
}
def get_folder_queryset(self):
- return Folder.objects.all()
+ return Folder.on_organization.all()
def get_queryset(self):
self.queryset = self.get_folder_queryset()
@@ -63,7 +65,6 @@ class FolderListView(SingleObjectListView):
class FolderCreateView(SingleObjectCreateView):
fields = ('label',)
- model = Folder
view_permission = permission_folder_create
def form_valid(self, form):
@@ -90,9 +91,12 @@ class FolderCreateView(SingleObjectCreateView):
'title': _('Create folder'),
}
+ def get_queryset(self):
+ return Folder.on_organization.all()
+
def folder_delete(request, folder_id):
- folder = get_object_or_404(Folder, pk=folder_id)
+ folder = get_object_or_404(Folder.on_organization, pk=folder_id)
try:
Permission.check_permissions(request.user, (permission_folder_delete,))
@@ -142,7 +146,7 @@ class FolderDetailView(DocumentListView):
}
def get_folder(self):
- folder = get_object_or_404(Folder, pk=self.kwargs['pk'])
+ folder = get_object_or_404(Folder.on_organization, pk=self.kwargs['pk'])
try:
Permission.check_permissions(
@@ -267,7 +271,7 @@ class DocumentFolderListView(FolderListView):
def folder_document_remove(request, folder_id, document_id=None, document_id_list=None):
post_action_redirect = None
- folder = get_object_or_404(Folder, pk=folder_id)
+ folder = get_object_or_404(Folder.on_organization, pk=folder_id)
if document_id:
queryset = Document.objects.filter(pk=document_id)
diff --git a/mayan/apps/organizations/__init__.py b/mayan/apps/organizations/__init__.py
new file mode 100644
index 0000000000..6167f9bfee
--- /dev/null
+++ b/mayan/apps/organizations/__init__.py
@@ -0,0 +1,3 @@
+from __future__ import unicode_literals
+
+default_app_config = 'organizations.apps.OrganizationApp'
diff --git a/mayan/apps/organizations/admin.py b/mayan/apps/organizations/admin.py
new file mode 100644
index 0000000000..3581b8c36d
--- /dev/null
+++ b/mayan/apps/organizations/admin.py
@@ -0,0 +1,11 @@
+from __future__ import unicode_literals
+
+from django.contrib import admin
+
+from .models import Organization
+
+
+@admin.register(Organization)
+class OrganizationAdmin(admin.ModelAdmin):
+ list_display = ('label',)
+ search_fields = ('label',)
diff --git a/mayan/apps/organizations/apps.py b/mayan/apps/organizations/apps.py
new file mode 100644
index 0000000000..847c307836
--- /dev/null
+++ b/mayan/apps/organizations/apps.py
@@ -0,0 +1,12 @@
+from __future__ import unicode_literals
+
+from django.apps import AppConfig
+
+from django.utils.translation import ugettext_lazy as _
+
+from common.apps import MayanAppConfig
+
+
+class OrganizationApp(AppConfig):
+ name = 'organizations'
+ verbose_name = _('Organizations')
diff --git a/mayan/apps/organizations/management.py b/mayan/apps/organizations/management.py
new file mode 100644
index 0000000000..da47183bd6
--- /dev/null
+++ b/mayan/apps/organizations/management.py
@@ -0,0 +1,43 @@
+"""
+Creates the default Organization object.
+"""
+
+from django.apps import apps
+from django.core.management.color import no_style
+from django.db import DEFAULT_DB_ALIAS, connections, router
+from django.db.models import signals
+
+
+def create_default_organization(app_config, verbosity=2, interactive=True, using=DEFAULT_DB_ALIAS, **kwargs):
+ try:
+ Organization = apps.get_model('organizations', 'Organization')
+ except LookupError:
+ return
+
+ if not router.allow_migrate(using, Organization):
+ return
+
+ if not Organization.objects.using(using).exists():
+ # The default settings set ORGANIZATION_ID = 1, and some tests in Django's test
+ # suite rely on this value. However, if database sequences are reused
+ # (e.g. in the test suite after flush/syncdb), it isn't guaranteed that
+ # the next id will be 1, so we coerce it. See #15573 and #16353. This
+ # can also crop up outside of tests - see #15346.
+ if verbosity >= 2:
+ print("Creating default Organization object")
+ Organization(pk=1, label='Default').save(using=using)
+
+ # We set an explicit pk instead of relying on auto-incrementation,
+ # so we need to reset the database sequence. See #17415.
+ sequence_sql = connections[using].ops.sequence_reset_sql(no_style(), [Organization])
+ if sequence_sql:
+ if verbosity >= 2:
+ print('Resetting sequence')
+ with connections[using].cursor() as cursor:
+ for command in sequence_sql:
+ cursor.execute(command)
+
+ Organization.objects.clear_cache()
+
+
+signals.post_migrate.connect(create_default_organization, sender=apps.get_app_config('organizations'))
diff --git a/mayan/apps/organizations/managers.py b/mayan/apps/organizations/managers.py
new file mode 100644
index 0000000000..48c9c31981
--- /dev/null
+++ b/mayan/apps/organizations/managers.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.core import checks
+from django.db import models
+from django.db.models.fields import FieldDoesNotExist
+
+
+class CurrentOrganizationManager(models.Manager):
+ "Use this to limit objects to those associated with the current organization."
+
+ def __init__(self, field_name=None):
+ super(CurrentOrganizationManager, self).__init__()
+ self.__field_name = field_name
+
+ def check(self, **kwargs):
+ errors = super(CurrentOrganizationManager, self).check(**kwargs)
+ errors.extend(self._check_field_name())
+ return errors
+
+ def _check_field_name(self):
+ field_name = self._get_field_name()
+ try:
+ field = self.model._meta.get_field(field_name)
+ except FieldDoesNotExist:
+ return [
+ checks.Error(
+ "CurrentOrganizationManager could not find a field named '%s'." % field_name,
+ hint=None,
+ obj=self,
+ id='organizations.E001',
+ )
+ ]
+
+ if not isinstance(field, (models.ForeignKey, models.ManyToManyField)):
+ return [
+ checks.Error(
+ "CurrentOrganizationManager cannot use '%s.%s' as it is not a ForeignKey or ManyToManyField." % (
+ self.model._meta.object_name, field_name
+ ),
+ hint=None,
+ obj=self,
+ id='organizations.E002',
+ )
+ ]
+
+ return []
+
+ def _get_field_name(self):
+ """ Return self.__field_name or 'organization' or 'organizations'. """
+
+ if not self.__field_name:
+ try:
+ self.model._meta.get_field('organization')
+ except FieldDoesNotExist:
+ self.__field_name = 'organizations'
+ else:
+ self.__field_name = 'organization'
+ return self.__field_name
+
+ def get_queryset(self):
+ return super(CurrentOrganizationManager, self).get_queryset().filter(
+ **{self._get_field_name() + '__id': settings.ORGANIZATION_ID})
diff --git a/mayan/apps/organizations/middleware.py b/mayan/apps/organizations/middleware.py
new file mode 100644
index 0000000000..d46001546e
--- /dev/null
+++ b/mayan/apps/organizations/middleware.py
@@ -0,0 +1,10 @@
+from .models import Organization
+
+
+class CurrentOrganizationMiddleware(object):
+ """
+ Middleware that sets `organization` attribute to request object.
+ """
+
+ def process_request(self, request):
+ request.organization = Organization.objects.get_current()
diff --git a/mayan/apps/organizations/migrations/0001_initial.py b/mayan/apps/organizations/migrations/0001_initial.py
new file mode 100644
index 0000000000..2c0b1e6246
--- /dev/null
+++ b/mayan/apps/organizations/migrations/0001_initial.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Organization',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('label', models.CharField(max_length=50, verbose_name='Label')),
+ ],
+ options={
+ 'ordering': ('label',),
+ 'verbose_name': 'Organization',
+ 'verbose_name_plural': 'Organizations',
+ },
+ bases=(models.Model,),
+ ),
+ ]
diff --git a/mayan/apps/organizations/migrations/__init__.py b/mayan/apps/organizations/migrations/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/mayan/apps/organizations/models.py b/mayan/apps/organizations/models.py
new file mode 100644
index 0000000000..93b0df81ce
--- /dev/null
+++ b/mayan/apps/organizations/models.py
@@ -0,0 +1,71 @@
+from __future__ import unicode_literals
+
+import string
+import warnings
+
+from django.core.exceptions import ImproperlyConfigured, ValidationError
+from django.db import models
+from django.db.models.signals import pre_save, pre_delete
+from django.utils.deprecation import RemovedInDjango19Warning
+from django.utils.encoding import python_2_unicode_compatible
+from django.utils.translation import ugettext_lazy as _
+
+ORGANIZATION_CACHE = {}
+
+
+class OrganizationManager(models.Manager):
+ def get_current(self):
+ """
+ Returns the current ``Organization`` based on the ORGANIZATION_ID in
+ the project's settings. The ``Organization`` object is cached the first
+ time it's retrieved from the database.
+ """
+ from django.conf import settings
+ try:
+ oid = settings.ORGANIZATION_ID
+ except AttributeError:
+ raise ImproperlyConfigured(
+ "You're using the Django \"organizations framework\" without "
+ "having set the ORGANIZATION_ID setting. Create a site in "
+ "your database and set the SITE_ID setting to fix this error."
+ )
+ try:
+ current_organization = ORGANIZATION_CACHE[oid]
+ except KeyError:
+ current_organization = self.get(pk=oid)
+ ORGANIZATION_CACHE[oid] = current_organization
+ return current_organization
+
+ def clear_cache(self):
+ """Clears the ``Organization`` object cache."""
+ global ORGANIZATION_CACHE
+ ORGANIZATION_CACHE = {}
+
+
+@python_2_unicode_compatible
+class Organization(models.Model):
+ label = models.CharField(max_length=50, verbose_name=_('Label'))
+ objects = OrganizationManager()
+
+ class Meta:
+ verbose_name = _('Organization')
+ verbose_name_plural = _('Organizations')
+ ordering = ('label',)
+
+ def __str__(self):
+ return self.label
+
+
+def clear_organization_cache(sender, **kwargs):
+ """
+ Clears the cache (if primed) each time a organization is saved or deleted
+ """
+ instance = kwargs['instance']
+ try:
+ del ORGANIZATION_CACHE[instance.pk]
+ except KeyError:
+ pass
+
+
+pre_save.connect(clear_organization_cache, sender=Organization)
+pre_delete.connect(clear_organization_cache, sender=Organization)
diff --git a/mayan/apps/organizations/shortcuts.py b/mayan/apps/organizations/shortcuts.py
new file mode 100644
index 0000000000..84480ac072
--- /dev/null
+++ b/mayan/apps/organizations/shortcuts.py
@@ -0,0 +1,8 @@
+from __future__ import unicode_literals
+
+from django.apps import apps
+
+
+def get_current_organization():
+ from .models import Organization
+ return Organization.objects.get_current().pk
diff --git a/mayan/apps/organizations/tests.py b/mayan/apps/organizations/tests.py
new file mode 100644
index 0000000000..cec5350d56
--- /dev/null
+++ b/mayan/apps/organizations/tests.py
@@ -0,0 +1,149 @@
+from __future__ import unicode_literals
+
+import unittest
+
+from django.apps import apps
+from django.conf import settings
+from django.core.exceptions import ObjectDoesNotExist, ValidationError
+from django.db import connections, router
+from django.http import HttpRequest
+from django.test import TestCase, modify_settings, override_settings
+
+from .management import create_default_organization
+from .middleware import CurrentOrganizationMiddleware
+from .models import Organization
+from .shortcuts import get_current_organization
+
+
+class OrganizationsFrameworkTests(TestCase):
+
+ def setUp(self):
+ Organization(id=settings.ORGANIZATION_ID, domain="example.com", name="example.com").save()
+
+ def test_organization_manager(self):
+ # Make sure that get_current() does not return a deleted Organization object.
+ s = Organization.objects.get_current()
+ self.assertTrue(isinstance(s, Organization))
+ s.delete()
+ self.assertRaises(ObjectDoesNotExist, Organization.objects.get_current)
+
+ def test_organization_cache(self):
+ # After updating a Organization object (e.g. via the admin), we shouldn't return a
+ # bogus value from the ORGANIZATION_CACHE.
+ organization = Organization.objects.get_current()
+ self.assertEqual("example.com", organization.name)
+ s2 = Organization.objects.get(id=settings.ORGANIZATION_ID)
+ s2.name = "Example organization"
+ s2.save()
+ organization = Organization.objects.get_current()
+ self.assertEqual("Example organization", organization.name)
+
+ def test_delete_all_organizations_clears_cache(self):
+ # When all organization objects are deleted the cache should also
+ # be cleared and get_current() should raise a DoesNotExist.
+ self.assertIsInstance(Organization.objects.get_current(), Organization)
+ Organization.objects.all().delete()
+ self.assertRaises(Organization.DoesNotExist, Organization.objects.get_current)
+
+ @override_settings(ALLOWED_HOSTS=['example.com'])
+ def test_get_current_organization(self):
+ # Test that the correct Organization object is returned
+ request = HttpRequest()
+ request.META = {
+ "SERVER_NAME": "example.com",
+ "SERVER_PORT": "80",
+ }
+ organization = get_current_organization(request)
+ self.assertTrue(isinstance(organization, Organization))
+ self.assertEqual(organization.id, settings.ORGANIZATION_ID)
+
+ # Test that an exception is raised if the organizations framework is installed
+ # but there is no matching Organization
+ organization.delete()
+ self.assertRaises(ObjectDoesNotExist, get_current_organization, request)
+
+ # A RequestOrganization is returned if the organizations framework is not installed
+ with self.modify_settings(INSTALLED_APPS={'remove': 'django.contrib.organizations'}):
+ organization = get_current_organization(request)
+ self.assertTrue(isinstance(organization, RequestOrganization))
+ self.assertEqual(organization.name, "example.com")
+
+ def test_domain_name_with_whitespaces(self):
+ # Regression for #17320
+ # Domain names are not allowed contain whitespace characters
+ organization = Organization(name="test name", domain="test test")
+ self.assertRaises(ValidationError, organization.full_clean)
+ organization.domain = "test\ttest"
+ self.assertRaises(ValidationError, organization.full_clean)
+ organization.domain = "test\ntest"
+ self.assertRaises(ValidationError, organization.full_clean)
+
+
+class JustOtherRouter(object):
+ def allow_migrate(self, db, model):
+ return db == 'other'
+
+
+@modify_settings(INSTALLED_APPS={'append': 'django.contrib.organizations'})
+class CreateDefaultOrganizationTests(TestCase):
+ multi_db = True
+
+ def setUp(self):
+ self.app_config = apps.get_app_config('organizations')
+ # Delete the organization created as part of the default migration process.
+ Organization.objects.all().delete()
+
+ def test_basic(self):
+ """
+ #15346, #15573 - create_default_organization() creates an example organization only if
+ none exist.
+ """
+ create_default_organization(self.app_config, verbosity=0)
+ self.assertEqual(Organization.objects.count(), 1)
+
+ create_default_organization(self.app_config, verbosity=0)
+ self.assertEqual(Organization.objects.count(), 1)
+
+ @unittest.skipIf('other' not in connections, "Requires 'other' database connection.")
+ def test_multi_db_with_router(self):
+ """
+ #16353, #16828 - The default organization creation should respect db routing.
+ """
+ old_routers = router.routers
+ router.routers = [JustOtherRouter()]
+ try:
+ create_default_organization(self.app_config, using='default', verbosity=0)
+ create_default_organization(self.app_config, using='other', verbosity=0)
+ self.assertFalse(Organization.objects.using('default').exists())
+ self.assertTrue(Organization.objects.using('other').exists())
+ finally:
+ router.routers = old_routers
+
+ @unittest.skipIf('other' not in connections, "Requires 'other' database connection.")
+ def test_multi_db(self):
+ create_default_organization(self.app_config, using='default', verbosity=0)
+ create_default_organization(self.app_config, using='other', verbosity=0)
+ self.assertTrue(Organization.objects.using('default').exists())
+ self.assertTrue(Organization.objects.using('other').exists())
+
+ def test_save_another(self):
+ """
+ #17415 - Another organization can be created right after the default one.
+
+ On some backends the sequence needs to be reset after saving with an
+ explicit ID. Test that there isn't a sequence collisions by saving
+ another organization. This test is only meaningful with databases that use
+ sequences for automatic primary keys such as PostgreSQL and Oracle.
+ """
+ create_default_organization(self.app_config, verbosity=0)
+ Organization(domain='example2.com', name='example2.com').save()
+
+
+class MiddlewareTest(TestCase):
+
+ def test_request(self):
+ """ Makes sure that the request has correct `organization` attribute. """
+ middleware = CurrentOrganizationMiddleware()
+ request = HttpRequest()
+ middleware.process_request(request)
+ self.assertEqual(request.organization.id, settings.ORGANIZATION_ID)
diff --git a/mayan/apps/tags/forms.py b/mayan/apps/tags/forms.py
index e8b70b496f..77820e95fe 100644
--- a/mayan/apps/tags/forms.py
+++ b/mayan/apps/tags/forms.py
@@ -21,7 +21,7 @@ class TagListForm(forms.Form):
logger.debug('user: %s', user)
super(TagListForm, self).__init__(*args, **kwargs)
- queryset = Tag.objects.all()
+ queryset = Tag.on_organization.all()
try:
Permission.check_permissions(user, (permission_tag_view,))
except PermissionDenied:
diff --git a/mayan/apps/tags/migrations/0007_tag_organization.py b/mayan/apps/tags/migrations/0007_tag_organization.py
new file mode 100644
index 0000000000..cd7fbd7b55
--- /dev/null
+++ b/mayan/apps/tags/migrations/0007_tag_organization.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+import organizations.shortcuts
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('organizations', '0001_initial'),
+ ('tags', '0006_documenttag'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='tag',
+ name='organization',
+ field=models.ForeignKey(default=organizations.shortcuts.get_current_organization, to='organizations.Organization'),
+ preserve_default=True,
+ ),
+ ]
diff --git a/mayan/apps/tags/models.py b/mayan/apps/tags/models.py
index 941654ffca..3b0a265437 100644
--- a/mayan/apps/tags/models.py
+++ b/mayan/apps/tags/models.py
@@ -11,11 +11,17 @@ from colorful.fields import RGBColorField
from acls.models import AccessControlList
from documents.models import Document
from documents.permissions import permission_document_view
+from organizations.models import Organization
+from organizations.managers import CurrentOrganizationManager
+from organizations.shortcuts import get_current_organization
from permissions import Permission
@python_2_unicode_compatible
class Tag(models.Model):
+ organization = models.ForeignKey(
+ Organization, default=get_current_organization
+ )
label = models.CharField(
db_index=True, max_length=128, unique=True, verbose_name=_('Label')
)
@@ -24,6 +30,9 @@ class Tag(models.Model):
Document, related_name='tags', verbose_name=_('Documents')
)
+ objects = models.Manager()
+ on_organization = CurrentOrganizationManager()
+
def __str__(self):
return self.label
diff --git a/mayan/apps/tags/views.py b/mayan/apps/tags/views.py
index 32e8234830..bfd48a33c0 100644
--- a/mayan/apps/tags/views.py
+++ b/mayan/apps/tags/views.py
@@ -33,10 +33,12 @@ logger = logging.getLogger(__name__)
class TagCreateView(SingleObjectCreateView):
extra_context = {'title': _('Create tag')}
fields = ('label', 'color')
- model = Tag
post_action_redirect = reverse_lazy('tags:tag_list')
view_permission = permission_tag_create
+ def get_queryset(self):
+ return Tag.on_organization.all()
+
def tag_attach(request, document_id=None, document_id_list=None):
if document_id:
@@ -144,17 +146,18 @@ class TagListView(SingleObjectListView):
return super(TagListView, self).get_queryset()
def get_tag_queryset(self):
- return Tag.objects.all()
+ return Tag.on_organization.all()
def tag_delete(request, tag_id=None, tag_id_list=None):
post_action_redirect = None
+ queryset = Tag.on_organization.all()
if tag_id:
- queryset = Tag.objects.filter(pk=tag_id)
+ queryset = organization.filter(pk=tag_id)
post_action_redirect = reverse('tags:tag_list')
elif tag_id_list:
- queryset = Tag.objects.filter(pk__in=tag_id_list)
+ queryset = organization.filter(pk__in=tag_id_list)
if not queryset:
messages.error(request, _('Must provide at least one tag.'))
@@ -221,7 +224,6 @@ def tag_multiple_delete(request):
class TagEditView(SingleObjectEditView):
fields = ('label', 'color')
- model = Tag
object_permission = permission_tag_edit
post_action_redirect = reverse_lazy('tags:tag_list')
@@ -231,10 +233,13 @@ class TagEditView(SingleObjectEditView):
'title': _('Edit tag: %s') % self.get_object(),
}
+ def get_queryset(self):
+ return Tag.on_organization.all()
+
class TagTaggedItemListView(DocumentListView):
def get_tag(self):
- return get_object_or_404(Tag, pk=self.kwargs['pk'])
+ return get_object_or_404(Tag.on_organization, pk=self.kwargs['pk'])
def get_document_queryset(self):
return self.get_tag().documents.all()
@@ -309,17 +314,20 @@ def tag_remove(request, document_id=None, document_id_list=None, tag_id=None, ta
}
template = 'appearance/generic_confirm.html'
+
+ queryset = Tag.on_organization.all()
+
if tag_id:
- tags = Tag.objects.filter(pk=tag_id)
+ tags = queryset.filter(pk=tag_id)
elif tag_id_list:
- tags = Tag.objects.filter(pk__in=tag_id_list)
+ tags = queryset.filter(pk__in=tag_id_list)
else:
template = 'appearance/generic_form.html'
if request.method == 'POST':
form = TagListForm(request.POST, user=request.user)
if form.is_valid():
- tags = Tag.objects.filter(pk=form.cleaned_data['tag'].pk)
+ tags = Tag.on_organization.filter(pk=form.cleaned_data['tag'].pk)
else:
if not tag_id and not tag_id_list:
form = TagListForm(user=request.user)
diff --git a/mayan/settings/base.py b/mayan/settings/base.py
index b10c746d48..f5fc541218 100644
--- a/mayan/settings/base.py
+++ b/mayan/settings/base.py
@@ -73,6 +73,7 @@ INSTALLED_APPS = (
'lock_manager',
'mimetype',
'navigation',
+ 'organizations',
'permissions',
'smart_settings',
'user_management',
@@ -113,6 +114,7 @@ MIDDLEWARE_CLASSES = (
'common.middleware.strip_spaces_widdleware.SpacelessMiddleware',
'authentication.middleware.login_required_middleware.LoginRequiredMiddleware',
'common.middleware.ajax_redirect.AjaxRedirect',
+ 'organizations.middleware.CurrentOrganizationMiddleware',
)
ROOT_URLCONF = 'mayan.urls'
@@ -284,3 +286,5 @@ SWAGGER_SETTINGS = {
# ------ Timezone --------
TIMEZONE_COOKIE_NAME = 'django_timezone'
TIMEZONE_SESSION_KEY = 'django_timezone'
+# ------ Organization -------
+ORGANIZATION_ID = 1