diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2023-10-02 16:39:42 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2024-04-16 16:38:32 +0200 |
commit | a7a0b8e6cf8d67cc50eefe79a65caa93f6059169 (patch) | |
tree | d83ad46dcd595fc282038dfd4200357f3c019f6c | |
parent | faf34feb2bcebd3fe4fa14f21aa65b49f76c886d (diff) | |
download | Ishtar-a7a0b8e6cf8d67cc50eefe79a65caa93f6059169.tar.bz2 Ishtar-a7a0b8e6cf8d67cc50eefe79a65caa93f6059169.zip |
🗃️ DB changes to manage user permissions
-rw-r--r-- | archaeological_context_records/migrations/0113_contextrecord_imports_updated.py | 4 | ||||
-rw-r--r-- | archaeological_files/migrations/0112_file_imports_updated.py | 4 | ||||
-rw-r--r-- | archaeological_finds/migrations/0113_auto_20231002_1617.py (renamed from archaeological_finds/migrations/0113_auto_20230922_1443.py) | 4 | ||||
-rw-r--r-- | archaeological_operations/migrations/0113_auto_20231002_1613.py (renamed from archaeological_operations/migrations/0113_auto_20230922_1443.py) | 4 | ||||
-rw-r--r-- | archaeological_warehouse/migrations/0119_auto_20231002_1617.py (renamed from archaeological_warehouse/migrations/0119_auto_20230922_1443.py) | 4 | ||||
-rw-r--r-- | changelog/fr/changelog_2023-01-25.md | 11 | ||||
-rw-r--r-- | ishtar_common/migrations/0230_auto_20231002_1613.py (renamed from ishtar_common/migrations/0230_auto_20230922_1443.py) | 8 | ||||
-rw-r--r-- | ishtar_common/migrations/0231_default_mandatory_keys.py | 2 | ||||
-rw-r--r-- | ishtar_common/models_common.py | 221 | ||||
-rw-r--r-- | ishtar_common/models_imports.py | 29 | ||||
-rw-r--r-- | ishtar_common/utils.py | 227 |
11 files changed, 276 insertions, 242 deletions
diff --git a/archaeological_context_records/migrations/0113_contextrecord_imports_updated.py b/archaeological_context_records/migrations/0113_contextrecord_imports_updated.py index bda2c3122..97b09dfcb 100644 --- a/archaeological_context_records/migrations/0113_contextrecord_imports_updated.py +++ b/archaeological_context_records/migrations/0113_contextrecord_imports_updated.py @@ -1,4 +1,4 @@ -# Generated by Django 2.2.24 on 2023-09-22 14:43 +# Generated by Django 2.2.24 on 2023-10-02 16:13 from django.db import migrations, models @@ -6,7 +6,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('ishtar_common', '0230_auto_20230922_1443'), + ('ishtar_common', '0230_auto_20231002_1613'), ('archaeological_context_records', '0112_migrate_created'), ] diff --git a/archaeological_files/migrations/0112_file_imports_updated.py b/archaeological_files/migrations/0112_file_imports_updated.py index 226f4988a..de242a6ba 100644 --- a/archaeological_files/migrations/0112_file_imports_updated.py +++ b/archaeological_files/migrations/0112_file_imports_updated.py @@ -1,4 +1,4 @@ -# Generated by Django 2.2.24 on 2023-09-22 14:43 +# Generated by Django 2.2.24 on 2023-10-02 16:17 from django.db import migrations, models @@ -6,7 +6,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('ishtar_common', '0230_auto_20230922_1443'), + ('ishtar_common', '0230_auto_20231002_1613'), ('archaeological_files', '0111_migrate_created'), ] diff --git a/archaeological_finds/migrations/0113_auto_20230922_1443.py b/archaeological_finds/migrations/0113_auto_20231002_1617.py index ba2e761f3..000e99de9 100644 --- a/archaeological_finds/migrations/0113_auto_20230922_1443.py +++ b/archaeological_finds/migrations/0113_auto_20231002_1617.py @@ -1,4 +1,4 @@ -# Generated by Django 2.2.24 on 2023-09-22 14:43 +# Generated by Django 2.2.24 on 2023-10-02 16:17 from django.db import migrations, models @@ -6,7 +6,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('ishtar_common', '0230_auto_20230922_1443'), + ('ishtar_common', '0230_auto_20231002_1613'), ('archaeological_finds', '0112_migrate_created'), ] diff --git a/archaeological_operations/migrations/0113_auto_20230922_1443.py b/archaeological_operations/migrations/0113_auto_20231002_1613.py index 7070b0c33..eab32be8c 100644 --- a/archaeological_operations/migrations/0113_auto_20230922_1443.py +++ b/archaeological_operations/migrations/0113_auto_20231002_1613.py @@ -1,4 +1,4 @@ -# Generated by Django 2.2.24 on 2023-09-22 14:43 +# Generated by Django 2.2.24 on 2023-10-02 16:13 from django.db import migrations, models @@ -6,7 +6,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('ishtar_common', '0230_auto_20230922_1443'), + ('ishtar_common', '0230_auto_20231002_1613'), ('archaeological_operations', '0112_migrate_created'), ] diff --git a/archaeological_warehouse/migrations/0119_auto_20230922_1443.py b/archaeological_warehouse/migrations/0119_auto_20231002_1617.py index 43020abc3..b05a88886 100644 --- a/archaeological_warehouse/migrations/0119_auto_20230922_1443.py +++ b/archaeological_warehouse/migrations/0119_auto_20231002_1617.py @@ -1,4 +1,4 @@ -# Generated by Django 2.2.24 on 2023-09-22 14:43 +# Generated by Django 2.2.24 on 2023-10-02 16:17 from django.db import migrations, models @@ -6,7 +6,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('ishtar_common', '0230_auto_20230922_1443'), + ('ishtar_common', '0230_auto_20231002_1613'), ('archaeological_warehouse', '0118_auto_20230807_1106'), ] diff --git a/changelog/fr/changelog_2023-01-25.md b/changelog/fr/changelog_2023-01-25.md index 95cc9a36f..82accf4f1 100644 --- a/changelog/fr/changelog_2023-01-25.md +++ b/changelog/fr/changelog_2023-01-25.md @@ -3,12 +3,13 @@ v4.0.XX - 2099-12-31 ### Fonctionnalités/améliorations ### - ajout de formulaire pré-imports -- formulaire d'imports: réorganisation de l'ordre des champs +- formulaire d'imports : réorganisation de l'ordre des champs - table des imports : - - visualisateur CSV intégré - - raffrachissement automatique de l'avancement - - réorganisation des champs - - amélioration de la présentation + - visualisateur CSV intégré + - rafraîchissement automatique de l'avancement + - réorganisation des champs + - amélioration de la présentation + ### Technique ### - relation de mise à jour entre imports et les éléments principaux diff --git a/ishtar_common/migrations/0230_auto_20230922_1443.py b/ishtar_common/migrations/0230_auto_20231002_1613.py index 7839e0cd0..ec409c5e2 100644 --- a/ishtar_common/migrations/0230_auto_20230922_1443.py +++ b/ishtar_common/migrations/0230_auto_20231002_1613.py @@ -1,8 +1,9 @@ -# Generated by Django 2.2.24 on 2023-09-22 14:43 +# Generated by Django 2.2.24 on 2023-10-02 16:13 import django.core.validators from django.db import migrations, models import django.db.models.deletion +import ishtar_common.utils class Migration(migrations.Migration): @@ -20,6 +21,7 @@ class Migration(migrations.Migration): ('slug', models.SlugField(max_length=100, unique=True, verbose_name='Slug')), ('description', models.TextField(blank=True, default='', verbose_name='Description')), ('available', models.BooleanField(default=True, verbose_name='Available')), + ('users', models.ManyToManyField(blank=True, to='ishtar_common.IshtarUser', verbose_name='Users')), ], options={ 'verbose_name': 'Importer - Group', @@ -29,7 +31,7 @@ class Migration(migrations.Migration): ), migrations.AlterModelOptions( name='import', - options={'verbose_name': 'Import - Import', 'verbose_name_plural': 'Import - Imports'}, + options={'permissions': (('view_own_import', 'Can view own Import'), ('add_own_import', 'Can add own Import'), ('change_own_import', 'Can change own Import'), ('delete_own_import', 'Can delete own Import')), 'verbose_name': 'Import - Import', 'verbose_name_plural': 'Import - Imports'}, ), migrations.AlterModelOptions( name='itemkey', @@ -131,7 +133,9 @@ class Migration(migrations.Migration): options={ 'verbose_name': 'Import - Group', 'verbose_name_plural': 'Import - Groups', + 'permissions': (('view_own_importgroup', 'Can view own Import Group'), ('add_own_importgroup', 'Can add own Import Group'), ('change_own_importgroup', 'Can change own Import Group'), ('delete_own_importgroup', 'Can delete own Import Group')), }, + bases=(models.Model, ishtar_common.utils.OwnPerms), ), migrations.AddField( model_name='import', diff --git a/ishtar_common/migrations/0231_default_mandatory_keys.py b/ishtar_common/migrations/0231_default_mandatory_keys.py index d364f01dc..b510976fb 100644 --- a/ishtar_common/migrations/0231_default_mandatory_keys.py +++ b/ishtar_common/migrations/0231_default_mandatory_keys.py @@ -30,7 +30,7 @@ def migrate(apps, __): class Migration(migrations.Migration): dependencies = [ - ('ishtar_common', '0230_auto_20230922_1443'), + ('ishtar_common', '0230_auto_20231002_1613'), ] operations = [ diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py index aa6a329c3..1033be9ed 100644 --- a/ishtar_common/models_common.py +++ b/ishtar_common/models_common.py @@ -75,6 +75,7 @@ from ishtar_common.utils import ( duplicate_item, get_generated_id, get_current_profile, + OwnPerms ) @@ -1762,226 +1763,6 @@ class LightHistorizedItem(BaseHistorizedItem): return self -class OwnPerms(object): - """ - Manage special permissions for object's owner - """ - - @classmethod - def get_query_owns(cls, ishtaruser): - """ - Query object to get own items - """ - return None # implement for each object - - def can_view(self, request): - if hasattr(self, "LONG_SLUG"): - perm = "view_" + self.LONG_SLUG - else: - perm = "view_" + self.SLUG - return self.can_do(request, perm) - - def can_edit(self, request): - if not getattr(request.user, "ishtaruser", None): - return False - ishtaruser = request.user.ishtaruser - slug = self.LONG_SLUG if hasattr(self, "LONG_SLUG") else self.SLUG - if ishtaruser.has_perm("change_" + slug, session=request.session): - return True - if not ishtaruser.has_perm("change_own_" + slug, session=request.session): - return False - return self.is_own(ishtaruser) - - def can_do(self, request, action_name): - """ - Check permission availability for the current object. - :param request: request object - :param action_name: action name eg: "change_find" - "own" variation is - checked - :return: boolean - """ - if not getattr(request.user, "ishtaruser", None): - return False - splited = action_name.split("_") - action_own_name = splited[0] + "_own_" + "_".join(splited[1:]) - user = request.user - if action_name == "view_findbasket": - action_own_name = "view_own_find" - action_name = "view_find" - return user.ishtaruser.has_right(action_name, request.session) or ( - user.ishtaruser.has_right(action_own_name, request.session) - and self.is_own(user.ishtaruser) - ) - - def is_own(self, user, alt_query_own=None): - """ - Check if the current object is owned by the user - """ - IshtarUser = apps.get_model("ishtar_common", "IshtarUser") - if isinstance(user, IshtarUser): - ishtaruser = user - elif hasattr(user, "ishtaruser"): - ishtaruser = user.ishtaruser - else: - return False - if not alt_query_own: - query = self.get_query_owns(ishtaruser) - else: - query = getattr(self, alt_query_own)(ishtaruser) - if not query: - return False - query &= Q(pk=self.pk) - return self.__class__.objects.filter(query).count() - - @classmethod - def has_item_of(cls, user): - """ - Check if the user own some items - """ - IshtarUser = apps.get_model("ishtar_common", "IshtarUser") - if isinstance(user, IshtarUser): - ishtaruser = user - elif hasattr(user, "ishtaruser"): - ishtaruser = user.ishtaruser - else: - return False - query = cls.get_query_owns(ishtaruser) - if not query: - return False - return cls.objects.filter(query).count() - - @classmethod - def _return_get_owns( - cls, owns, values, get_short_menu_class, label_key="cached_label" - ): - if not owns: - return [] - sorted_values = [] - if hasattr(cls, "BASKET_MODEL"): - owns_len = len(owns) - for idx, item in enumerate(reversed(owns)): - if get_short_menu_class: - item = item[0] - if type(item) == cls.BASKET_MODEL: - basket = owns.pop(owns_len - idx - 1) - sorted_values.append(basket) - sorted_values = list(reversed(sorted_values)) - if not values: - if not get_short_menu_class: - return sorted_values + list( - sorted(owns, key=lambda x: getattr(x, label_key) or "") - ) - return sorted_values + list( - sorted(owns, key=lambda x: getattr(x[0], label_key) or "") - ) - if not get_short_menu_class: - return sorted_values + list(sorted(owns, key=lambda x: x[label_key] or "")) - return sorted_values + list(sorted(owns, key=lambda x: x[0][label_key] or "")) - - @classmethod - def get_owns( - cls, - user, - replace_query=None, - limit=None, - values=None, - get_short_menu_class=False, - menu_filtr=None, - ): - """ - Get Own items - """ - if not replace_query: - replace_query = {} - if hasattr(user, "is_authenticated") and not user.is_authenticated: - returned = cls.objects.filter(pk__isnull=True) - if values: - returned = [] - return returned - IshtarUser = apps.get_model("ishtar_common", "IshtarUser") - if isinstance(user, User): - try: - ishtaruser = IshtarUser.objects.get(user_ptr=user) - except IshtarUser.DoesNotExist: - returned = cls.objects.filter(pk__isnull=True) - if values: - returned = [] - return returned - elif isinstance(user, IshtarUser): - ishtaruser = user - else: - if values: - return [] - return cls.objects.filter(pk__isnull=True) - items = [] - if hasattr(cls, "BASKET_MODEL"): - items = list(cls.BASKET_MODEL.objects.filter(user=ishtaruser).all()) - query = cls.get_query_owns(ishtaruser) - if not query and not replace_query: - returned = cls.objects.filter(pk__isnull=True) - if values: - returned = [] - return returned - if query: - q = cls.objects.filter(query) - else: # replace_query - q = cls.objects.filter(replace_query) - if values: - q = q.values(*values) - if limit: - items += list(q.order_by("-pk")[:limit]) - else: - items += list(q.order_by(*cls._meta.ordering).all()) - if get_short_menu_class: - if values: - if "id" not in values: - raise NotImplementedError( - "Call of get_owns with get_short_menu_class option and" - " no 'id' in values is not implemented" - ) - my_items = [] - for i in items: - if hasattr(cls, "BASKET_MODEL") and type(i) == cls.BASKET_MODEL: - dct = dict([(k, getattr(i, k)) for k in values]) - my_items.append( - (dct, cls.BASKET_MODEL.get_short_menu_class(i.pk)) - ) - else: - my_items.append((i, cls.get_short_menu_class(i["id"]))) - items = my_items - else: - items = [(i, cls.get_short_menu_class(i.pk)) for i in items] - return items - - @classmethod - def _get_query_owns_dicts(cls, ishtaruser): - """ - List of query own dict to construct the query. - Each dict is joined with an AND operator, each dict key, values are - joined with OR operator - """ - return [] - - @classmethod - def _construct_query_own(cls, prefix, dct_list): - q = None - for subquery_dict in dct_list: - subquery = None - for k in subquery_dict: - subsubquery = Q(**{prefix + k: subquery_dict[k]}) - if subquery: - subquery |= subsubquery - else: - subquery = subsubquery - if not subquery: - continue - if q: - q &= subquery - else: - q = subquery - return q - - class DocumentItem: ALT_NAMES = { "documents__image__isnull": SearchAltName( diff --git a/ishtar_common/models_imports.py b/ishtar_common/models_imports.py index ea2f0f549..af907d44d 100644 --- a/ishtar_common/models_imports.py +++ b/ishtar_common/models_imports.py @@ -74,7 +74,8 @@ from ishtar_common.utils import ( put_session_message, put_session_var, reverse_coordinates, - update_data + update_data, + OwnPerms ) from ishtar_common.data_importer import ( Importer, @@ -416,6 +417,7 @@ class ImporterGroup(models.Model): _("Description"), blank=True, default="" ) available = models.BooleanField(_("Available"), default=True) + users = models.ManyToManyField("IshtarUser", verbose_name=_("Users"), blank=True) class Meta: verbose_name = _("Importer - Group") @@ -1338,7 +1340,7 @@ IMPORT_GEOMETRY = { } -class BaseImport(models.Model): +class BaseImport(models.Model, OwnPerms): user = models.ForeignKey( "IshtarUser", blank=True, null=True, on_delete=models.SET_NULL ) @@ -1412,6 +1414,15 @@ class BaseImport(models.Model): q = q.filter(user=ishtar_user) return q + @classmethod + def get_query_owns(cls, ishtaruser): + return cls._construct_query_own( + "", + [ + {"importer_type__users__pk": ishtaruser.pk}, + ], + ) + @property def group_prefix(self): return "" @@ -1465,7 +1476,14 @@ class ImportGroup(BaseImport): class Meta: verbose_name = _("Import - Group") verbose_name_plural = _("Import - Groups") + permissions = ( + ("view_own_importgroup", "Can view own Import Group"), + ("add_own_importgroup", "Can add own Import Group"), + ("change_own_importgroup", "Can change own Import Group"), + ("delete_own_importgroup", "Can delete own Import Group"), + ) ADMIN_SECTION = _("Imports") + SLUG = "importgroup" def __str__(self): return f"{self.name} ({self.importer_type.name})" @@ -1848,7 +1866,14 @@ class Import(BaseImport): class Meta: verbose_name = _("Import - Import") verbose_name_plural = _("Import - Imports") + permissions = ( + ("view_own_import", "Can view own Import"), + ("add_own_import", "Can add own Import"), + ("change_own_import", "Can change own Import"), + ("delete_own_import", "Can delete own Import"), + ) ADMIN_SECTION = _("Imports") + SLUG = "import" def __str__(self): return "{} | {}".format(self.name or "-", self.importer_type) diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 4e50c506c..7b708cd76 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -51,7 +51,7 @@ from django import forms from django.apps import apps from django.conf import settings from django.conf.urls import url -from django.contrib.auth.models import Permission +from django.contrib.auth.models import Permission, User from django.contrib.auth.hashers import Argon2PasswordHasher as BaseArgon2PasswordHasher from django.contrib.contenttypes.models import ContentType from django.contrib.gis.geos import GEOSGeometry @@ -64,6 +64,7 @@ from django.core.files.storage import FileSystemStorage from django.core.validators import EMPTY_VALUES from django.urls import reverse from django.db import models +from django.db.models import Q from django.http import HttpResponseRedirect from django.utils.crypto import get_random_string from django.utils.datastructures import MultiValueDict as BaseMultiValueDict @@ -274,6 +275,228 @@ def check_model_access_control(request, model, available_perms=None): return allowed, own +class OwnPerms: + """ + Manage special permissions for object's owner + """ + + @classmethod + def get_query_owns(cls, ishtaruser): + """ + Query object to get own items + """ + return None # implement for each object + + def can_view(self, request): + if hasattr(self, "LONG_SLUG"): + perm = "view_" + self.LONG_SLUG + else: + perm = "view_" + self.SLUG + return self.can_do(request, perm) + + def can_edit(self, request): + if not getattr(request.user, "ishtaruser", None): + return False + ishtaruser = request.user.ishtaruser + slug = self.LONG_SLUG if hasattr(self, "LONG_SLUG") else self.SLUG + if ishtaruser.has_perm("change_" + slug, session=request.session): + return True + if not ishtaruser.has_perm("change_own_" + slug, session=request.session): + return False + return self.is_own(ishtaruser) + + def can_do(self, request, action_name): + """ + Check permission availability for the current object. + :param request: request object + :param action_name: action name eg: "change_find" - "own" variation is + checked + :return: boolean + """ + if not getattr(request.user, "ishtaruser", None): + return False + splited = action_name.split("_") + action_own_name = splited[0] + "_own_" + "_".join(splited[1:]) + user = request.user + if action_name == "view_findbasket": + action_own_name = "view_own_find" + action_name = "view_find" + return user.ishtaruser.has_right(action_name, request.session) or ( + user.ishtaruser.has_right(action_own_name, request.session) + and self.is_own(user.ishtaruser) + ) + + def is_own(self, user, alt_query_own=None): + """ + Check if the current object is owned by the user + """ + IshtarUser = apps.get_model("ishtar_common", "IshtarUser") + if isinstance(user, IshtarUser): + ishtaruser = user + elif hasattr(user, "ishtaruser"): + ishtaruser = user.ishtaruser + else: + return False + if not alt_query_own: + query = self.get_query_owns(ishtaruser) + else: + query = getattr(self, alt_query_own)(ishtaruser) + if not query: + return False + query &= Q(pk=self.pk) + return self.__class__.objects.filter(query).count() + + @classmethod + def has_item_of(cls, user): + """ + Check if the user own some items + """ + IshtarUser = apps.get_model("ishtar_common", "IshtarUser") + if isinstance(user, IshtarUser): + ishtaruser = user + elif hasattr(user, "ishtaruser"): + ishtaruser = user.ishtaruser + else: + return False + query = cls.get_query_owns(ishtaruser) + if not query: + return False + return cls.objects.filter(query).count() + + @classmethod + def _return_get_owns( + cls, owns, values, get_short_menu_class, label_key="cached_label" + ): + if not owns: + return [] + sorted_values = [] + if hasattr(cls, "BASKET_MODEL"): + owns_len = len(owns) + for idx, item in enumerate(reversed(owns)): + if get_short_menu_class: + item = item[0] + if type(item) == cls.BASKET_MODEL: + basket = owns.pop(owns_len - idx - 1) + sorted_values.append(basket) + sorted_values = list(reversed(sorted_values)) + if not values: + if not get_short_menu_class: + return sorted_values + list( + sorted(owns, key=lambda x: getattr(x, label_key) or "") + ) + return sorted_values + list( + sorted(owns, key=lambda x: getattr(x[0], label_key) or "") + ) + if not get_short_menu_class: + return sorted_values + list(sorted(owns, key=lambda x: x[label_key] or "")) + return sorted_values + list(sorted(owns, key=lambda x: x[0][label_key] or "")) + + @classmethod + def get_owns( + cls, + user, + replace_query=None, + limit=None, + values=None, + get_short_menu_class=False, + menu_filtr=None, + ): + """ + Get Own items + """ + if not replace_query: + replace_query = {} + if hasattr(user, "is_authenticated") and not user.is_authenticated: + returned = cls.objects.filter(pk__isnull=True) + if values: + returned = [] + return returned + IshtarUser = apps.get_model("ishtar_common", "IshtarUser") + if isinstance(user, User): + try: + ishtaruser = IshtarUser.objects.get(user_ptr=user) + except IshtarUser.DoesNotExist: + returned = cls.objects.filter(pk__isnull=True) + if values: + returned = [] + return returned + elif isinstance(user, IshtarUser): + ishtaruser = user + else: + if values: + return [] + return cls.objects.filter(pk__isnull=True) + items = [] + if hasattr(cls, "BASKET_MODEL"): + items = list(cls.BASKET_MODEL.objects.filter(user=ishtaruser).all()) + query = cls.get_query_owns(ishtaruser) + if not query and not replace_query: + returned = cls.objects.filter(pk__isnull=True) + if values: + returned = [] + return returned + if query: + q = cls.objects.filter(query) + else: # replace_query + q = cls.objects.filter(replace_query) + if values: + q = q.values(*values) + if limit: + items += list(q.order_by("-pk")[:limit]) + else: + items += list(q.order_by(*cls._meta.ordering).all()) + if get_short_menu_class: + if values: + if "id" not in values: + raise NotImplementedError( + "Call of get_owns with get_short_menu_class option and" + " no 'id' in values is not implemented" + ) + my_items = [] + for i in items: + if hasattr(cls, "BASKET_MODEL") and type(i) == cls.BASKET_MODEL: + dct = dict([(k, getattr(i, k)) for k in values]) + my_items.append( + (dct, cls.BASKET_MODEL.get_short_menu_class(i.pk)) + ) + else: + my_items.append((i, cls.get_short_menu_class(i["id"]))) + items = my_items + else: + items = [(i, cls.get_short_menu_class(i.pk)) for i in items] + return items + + @classmethod + def _get_query_owns_dicts(cls, ishtaruser): + """ + List of query own dict to construct the query. + Each dict is joined with an AND operator, each dict key, values are + joined with OR operator + """ + return [] + + @classmethod + def _construct_query_own(cls, prefix, dct_list): + q = None + for subquery_dict in dct_list: + subquery = None + for k in subquery_dict: + subsubquery = Q(**{prefix + k: subquery_dict[k]}) + if subquery: + subquery |= subsubquery + else: + subquery = subsubquery + if not subquery: + continue + if q: + q &= subquery + else: + q = subquery + return q + + + + def update_data(data, new_data, merge=False): """ Update a data directory taking account of key detail @@ -286,7 +509,7 @@ def update_data(data, new_data, merge=False): if new_data: return new_data return data - if new_data and data_2 != data: + if new_data and new_data != data: return data + " ; " + new_data return data for k in data: |