From: Yoan Le Clanche Date: Tue, 29 Apr 2025 15:01:11 +0000 (+0200) Subject: Fix postman X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=6cc19957a785bc361e20c951359227007e906a00;p=teleforma.git Fix postman --- diff --git a/poetry.lock b/poetry.lock index 68beae20..de0364ef 100644 --- a/poetry.lock +++ b/poetry.lock @@ -633,14 +633,21 @@ files = [ [[package]] name = "dj-pagination" -version = "2.5.0" +version = "2.5.0+poly.2024.1.11" description = "Django + Pagination Made Easy" optional = false python-versions = "*" -files = [ - {file = "dj-pagination-2.5.0.tar.gz", hash = "sha256:860301cdc79edc0712008921037b2341271d3a55586bc34fad072e74c8e800c4"}, - {file = "dj_pagination-2.5.0-py3-none-any.whl", hash = "sha256:2d65aac791abe7b5a5cd09cd0735c76dcd3a932ac1a56e1dffea441937f886b7"}, -] +files = [] +develop = false + +[package.dependencies] +Django = "<5.1" + +[package.source] +type = "git" +url = "https://github.com/Polyconseil/dj-pagination.git" +reference = "HEAD" +resolved_reference = "d2096bed8ac34d46430457df76afd5434417dc3c" [[package]] name = "django" @@ -1910,6 +1917,7 @@ optional = false python-versions = "<4,>=3.7" files = [ {file = "reportlab-4.4.0-py3-none-any.whl", hash = "sha256:0a993f1d4a765fcbdf4e26adc96b3351004ebf4d27583340595ba7edafebec32"}, + {file = "reportlab-4.4.0.tar.gz", hash = "sha256:a64d85513910e246c21dc97ccc3c9054a1d44370bf8fc1fab80af937814354d5"}, ] [package.dependencies] @@ -2713,4 +2721,4 @@ testing = ["coverage[toml]", "zope.event", "zope.testing"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "0bb9bb0f7644d8a2deadd26a1f7498537704175d49c8417b799f04a197bb16dc" +content-hash = "03c684a2b7b6e6f33469e2af83343c1567758e790bd469c0c4aeb32e94693423" diff --git a/pyproject.toml b/pyproject.toml index 8cbe4317..4402d0bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,7 @@ docutils = "0.17.1" django = "4.2" djangorestframework = "3.16.0" django-debug-toolbar = "3.2.1" -dj-pagination = "2.5.0" +dj-pagination = {git = "https://github.com/Polyconseil/dj-pagination.git"} django-jazzmin = "2.4.7" django-json-rpc = {git = "https://github.com/Parisson/django-json-rpc.git"} django-nvd3 = "0.9.7" diff --git a/teleforma/postman.py b/teleforma/postman.py index 7a9b5b8f..c6b3ecd6 100644 --- a/teleforma/postman.py +++ b/teleforma/postman.py @@ -1,5 +1,6 @@ # some patches for postman +from typing import Any, cast from django.db import models from django.db.models.expressions import RawSQL from django.db.models.query import QuerySet @@ -11,53 +12,70 @@ from postman.models import MessageManager, OPTION_MESSAGES MessageManager._folder_old = MessageManager._folder -def _folder(self, related, filters, option=None, order_by=None, query_dict=None): - """Base code, in common to the folders.""" - search = None - if query_dict: - search = query_dict.get('search') - qs = self.all() if option == OPTION_MESSAGES else QuerySet(self.model, PostmanQuery(self.model), using=self._db) - if related: - qs = qs.select_related(*related) - if order_by: - qs = qs.order_by(order_by) - if isinstance(filters, (list, tuple)): - lookups = models.Q() - for filter in filters: - lookups |= models.Q(**filter) - else: - lookups = models.Q(**filters) - - if search: - lookups &= models.Q(subject__icontains=search)\ - | models.Q(body__icontains=search)\ - | models.Q(sender__username__icontains=search)\ - | models.Q(sender__first_name__icontains=search)\ - | models.Q(sender__last_name__icontains=search)\ - | models.Q(recipient__first_name__icontains=search)\ - | models.Q(recipient__last_name__icontains=search) - if option == OPTION_MESSAGES: - qs = qs.filter(lookups) - # Adding a 'count' attribute, to be similar to the by-conversation case, - # should not be necessary. Otherwise add: - # .extra(select={'count': 'SELECT 1'}) - else: - qs = qs.annotate(count=RawSQL('{0}.count'.format(qs.query.pm_alias_prefix), ())) - qs.query.pm_set_extra(table=( - self.filter(lookups, thread_id__isnull=True).annotate(count=Value(0, IntegerField()))\ - .values_list('id', 'count').order_by(), - # use separate annotate() to keep control of the necessary order - self.filter(lookups, thread_id__isnull=False).values('thread').annotate(id=models.Max('pk')).annotate(count=models.Count('pk'))\ - .values_list('id', 'count').order_by(), - )) - if query_dict: - limit = query_dict.get('limit') - if limit: # at end because doc says "Further filtering or ordering of a sliced queryset is prohibited..." - try: - i = int(limit) - qs = qs[:i] - except: # just ignore any bad format - pass - return qs - -MessageManager._folder = _folder \ No newline at end of file + + +def _folder( + self, + related: tuple[str, ...] | None, + filters: dict[str, Any] | list[dict[str, Any]] | tuple[dict[str, Any], dict[str, Any]], + option: str | None = None, + order_by: str | None = None, + query_dict: dict[str, Any] | None = None + ): + """Base code, in common to the folders. Patched to add search""" + search = None + if query_dict: + search = query_dict.get('search') + qs = self.all() if option == OPTION_MESSAGES else QuerySet['Message'](self.model, PostmanQuery(self.model), using=self._db) + if related: + qs = qs.select_related(*related) + if order_by: + qs = qs.order_by(order_by) + if isinstance(filters, (list, tuple)): + lookups = models.Q() + for filter in filters: + lookups |= models.Q(**filter) + else: + lookups = models.Q(**filters) + + if search: + lookups &= models.Q(subject__icontains=search)\ + | models.Q(body__icontains=search)\ + | models.Q(sender__username__icontains=search)\ + | models.Q(sender__first_name__icontains=search)\ + | models.Q(sender__last_name__icontains=search)\ + | models.Q(recipient__first_name__icontains=search)\ + | models.Q(recipient__last_name__icontains=search) + if option == OPTION_MESSAGES: + qs = qs.filter(lookups) + # Adding a 'count' attribute, to be similar to the by-conversation case, + # should not be necessary. Otherwise add: + # .extra(select={'count': 'SELECT 1'}) + else: + qs = qs.annotate(count=RawSQL('{0}.count'.format(cast(PostmanQuery, qs.query).pm_alias_prefix), ())) + query = cast(PostmanQuery, qs.query) + alias_id = query.pm_alias_id + query.pm_set_extra(table=( + self.filter(lookups, thread_id__isnull=True)\ + # Dj 4.0 imposes its col aliases (as 'colN'), for combinator sql, if not explicitly defined. + # can't reuse 'id' because "ValueError: The annotation 'id' conflicts with a field on the model.". + .annotate(**{alias_id: models.F('pk')})\ + .annotate(count=models.Value(0, models.IntegerField()))\ + .values_list(alias_id, 'count').order_by(), + # use separate annotate() to keep control of the necessary order + self.filter(lookups, thread_id__isnull=False).values('thread')\ + .annotate(**{alias_id: models.Max('pk')})\ + .annotate(count=models.Count('pk'))\ + .values_list(alias_id, 'count').order_by(), + )) + if query_dict: + limit = query_dict.get('limit') + if limit: # at end because doc says "Further filtering or ordering of a sliced queryset is prohibited..." + try: + i = int(limit) + qs = qs[:i] + except: # just ignore any bad format + pass + return qs + +MessageManager._folder = _folder