コード例 #1
0
    def test_q_serializer_03(self):
        "AND"
        self.login()
        self._create_contacts()

        q = Q(last_name=self.adrian.last_name) & Q(first_name__startswith='Ad')
        self._assertQIsOK(q, [self.adrian])

        str_q = QSerializer().dumps(q)
        self._assertQEqual(FakeContact, q, QSerializer().loads(str_q))
コード例 #2
0
    def test_q_serializer_06(self):
        "Dates"
        self.login()
        self._create_contacts()

        q = Q(birthday__gt=date(year=2000, month=1, day=1))
        self._assertQIsOK(q, [self.adrian])

        str_q = QSerializer().dumps(q)
        self._assertQEqual(FakeContact, q, QSerializer().loads(str_q))
コード例 #3
0
    def test_q_serializer_04(self):
        "OR"
        self.login()
        self._create_contacts()

        q = Q(first_name=self.adrian.first_name) | Q(
            first_name__startswith='Ric')
        self._assertQIsOK(q, [self.richard, self.adrian])

        str_q = QSerializer().dumps(q)
        self._assertQEqual(FakeContact, q, QSerializer().loads(str_q))
コード例 #4
0
    def test_q_serializer_05(self):
        "NOT"
        self.login()
        self._create_contacts()

        q = ~Q(first_name=self.adrian.first_name) & Q(
            last_name=self.adrian.last_name)
        self._assertQIsOK(q, [self.marianne])

        str_q = QSerializer().dumps(q)
        self._assertQEqual(FakeContact, q, QSerializer().loads(str_q))
コード例 #5
0
    def test_q_serializer_10(self):
        "Value is a model instance"
        self.login()
        self._create_contacts()

        q = Q(position=self.baker)
        self._assertQIsOK(q, [self.marianne])

        qsr = QSerializer()
        str_q = qsr.dumps(q)
        self._assertQEqual(FakeContact, q, qsr.loads(str_q))
コード例 #6
0
    def test_q_serializer_11(self):
        "__in=[...] + model instance"
        self.login()
        self._create_contacts()

        q = Q(position__in=[self.boxer, self.fighter])
        self._assertQIsOK(q, [self.richard, self.adrian])

        qsr = QSerializer()
        str_q = qsr.dumps(q)
        self._assertQEqual(FakeContact, q, qsr.loads(str_q))
コード例 #7
0
    def test_q_serializer_01(self):
        self.login()
        self._create_contacts()

        q1 = Q(last_name=self.adrian.last_name)
        self._assertQIsOK(q1, [self.adrian, self.marianne])

        str_q = QSerializer().dumps(q1)
        self.assertIsInstance(str_q, str)

        q2 = QSerializer().loads(str_q)
        self.assertIsInstance(q2, Q)
        self._assertQEqual(FakeContact, q1, q2)
コード例 #8
0
    def test_q_serializer_08(self):
        "Range."
        user = self.create_user()

        create_orga = partial(FakeOrganisation.objects.create, user=user)
        create_orga(name='Vallée des rois', capital=15000)
        o2 = create_orga(name='Paxtown', capital=5000)
        create_orga(name='Zotis incorporation', capital=200)

        q = Q(capital__range=[1000, 10000])
        self._assertQIsOK(q, [o2])

        str_q = QSerializer().dumps(q)
        self._assertQEqual(FakeOrganisation, q, QSerializer().loads(str_q))
コード例 #9
0
    def register_in_session(self, request):
        serialized = {**self.__dict__}

        if self.extra_q is not None:
            serialized['extra_q'] = QSerializer().dumps(self.extra_q)

        request.session[self.url] = serialized
コード例 #10
0
    def test_q_serializer_07(self):
        "Datetimes"
        user = self.create_user()

        create_dt = partial(self.create_datetime, year=2015, month=2, minute=0)
        create_act = partial(FakeActivity.objects.create,
                             user=user,
                             type=self._create_activity_type())
        acts = [
            create_act(title='T#1', start=create_dt(day=19, hour=8)),
            create_act(title='T#2', start=create_dt(day=19, hour=12)),
        ]

        q = Q(start__lt=create_dt(day=19, hour=9))
        self._assertQIsOK(q, [acts[0]])

        str_q = QSerializer().dumps(q)
        self._assertQEqual(FakeActivity, q, QSerializer().loads(str_q))
コード例 #11
0
    def test_q_serializer_02(self):
        "2 conditions + operator"
        user = self.create_user()

        create_contact = partial(FakeContact.objects.create, user=user)
        adrian = create_contact(first_name='Adrian', last_name='Velbà')
        create_contact(first_name='Marianne', last_name='Velbà')
        create_contact(first_name='Richard', last_name='Aldana')

        q1 = Q(last_name=adrian.last_name, first_name__startswith='Ad')
        self._assertQIsOK(q1, [adrian])

        str_q = QSerializer().dumps(q1)
        self.assertIsInstance(str_q, str)

        q2 = QSerializer().loads(str_q)
        self.assertIsInstance(q2, Q)
        self._assertQEqual(FakeContact, q1, q2)
コード例 #12
0
 def detailview_display(self, context):
     folder_id = context['object'].id
     q_dict = {'linked_folder': folder_id}
     return self._render(
         self.get_template_context(
             context,
             Document.objects.filter(**q_dict),
             # Document.objects.filter(is_deleted=False, **q_dict), TODO: problem deleted docs avoid folder deletion...
             q_filter=QSerializer().dumps(Q(**q_dict)),
         ))
コード例 #13
0
ファイル: test_mass_export.py プロジェクト: mrjmad/creme_crm
    def test_extra_filter(self):
        self.login()
        self._build_hf_n_contacts()

        response = self.assertGET200(
            self._build_contact_dl_url(
                extra_q=QSerializer().dumps(Q(last_name='Wong'))), )

        result = [force_str(line) for line in response.content.splitlines()]
        self.assertEqual(2, len(result))
        self.assertEqual('"","Wong","Edward","","is a girl"', result[1])
コード例 #14
0
ファイル: lv_url.py プロジェクト: mrjmad/creme_crm
    def __call__(self, q_filter: Optional[dict] = None) -> Optional[str]:
        fmt = self._fmt

        if not fmt:
            return None

        final_q = self._common_q & Q(**q_filter) if q_filter else self._common_q

        return fmt.format(
            QSerializer().dumps(final_q) if final_q else ''
        )
コード例 #15
0
    def get_state(cls, request, url=None) -> Optional['ListViewState']:
        lvs = None
        data = request.session.get(url or request.path)

        if data is not None:
            lvs = cls()

            for k, v in data.items():
                setattr(lvs, k, v)

            if lvs.extra_q is not None:
                lvs.extra_q = QSerializer().loads(lvs.extra_q)

        return lvs
コード例 #16
0
    def test_q_serializer_12(self):
        "__in=QuerySet -> error"
        self.login()
        self._create_contacts()

        q = Q(position__in=FakePosition.objects.filter(title__startswith='B'))
        self._assertQIsOK(q, [self.richard, self.marianne])

        qsr = QSerializer()
        self.assertRaises(SerializationError, qsr.dumps, q)

        q = Q(position__in=FakePosition.objects.filter(
            title__startswith='B').values_list('id', flat=True), )
        self._assertQIsOK(q, [self.richard, self.marianne])
        self.assertRaises(SerializationError, qsr.dumps, q)
コード例 #17
0
ファイル: listview.py プロジェクト: HybirdCorp/creme_crm-2.0
def _build_extrafilter(arguments, extra_filter=None):
    json_q_filter = arguments.get('q_filter')
    q_filter = Q()
    serializer = QSerializer()

    # TODO: better validation of q_filter ? (corresponding EntityCell allowed + searchable ?)
    #  - limit the max depth of sub-fields chain ?
    #  - do no allow all fields ?
    if json_q_filter:
        try:
            q_filter = serializer.loads(json_q_filter)
        except:
            try:
                q_filter = get_q_from_dict(
                    _clean_value(json_q_filter, json_load, {}))
            except:
                raise
            else:
                warnings.warn(
                    'Old format for "q_filter" is deprecated is used : {}'.
                    format(json_q_filter), DeprecationWarning)

    return (serializer.dumps(q_filter),
            q_filter if extra_filter is None else q_filter & extra_filter)
コード例 #18
0
    def build_q_filter(self, q_filter):
        extra_filter = False
        basic_q = Q(mime_type__name__startswith=MIMETYPE_PREFIX_IMG)

        if q_filter is not None:
            if isinstance(q_filter, dict):
                q_filter = Q(**q_filter)

            # NB: Q has not method __equal__(), so we compare serialized Q objects.
            serialize = QSerializer().serialize
            extra_filter = (serialize(q_filter) != serialize(basic_q))
            final_q = (basic_q & q_filter) if extra_filter else q_filter
        else:
            final_q = basic_q

        return final_q, extra_filter
コード例 #19
0
    def get_state(cls, request, url=None):
        lvs = None
        data = request.session.get(url or request.path)

        if data is not None:
            # # lvs = object.__new__(ListViewState)  # NB: causes problem on attribute change (renaming...)
            # lvs = ListViewState()
            lvs = cls()

            for k, v in data.items():
                setattr(lvs, k, v)

            if lvs.extra_q is not None:
                lvs.extra_q = QSerializer().loads(lvs.extra_q)

        return lvs
コード例 #20
0
    def get_requested_q(self):
        arg_name = self.requested_q_arg
        json_q_filter = self.arguments.get(arg_name)

        # TODO: better validation (eg: corresponding EntityCell allowed + searchable ?) ?
        #  - limit the max depth of sub-fields chain ?
        #  - do no allow all fields ?
        if json_q_filter:
            try:
                return QSerializer().loads(json_q_filter)
            except JSONDecodeError:
                logger.exception(
                    'Error when decoding the argument "%s": %s',
                    arg_name,
                    json_q_filter,
                )

        return Q()
コード例 #21
0
ファイル: graph.py プロジェクト: mrjmad/creme_crm-2.1
    def __call__(self, q_filter=None):
        fmt = self._fmt

        return fmt.format(QSerializer().dumps(Q(**q_filter)) if q_filter is not None else '') if fmt else None
コード例 #22
0
ファイル: test_reports.py プロジェクト: mrjmad/creme_crm
    def test_report_graph_fetcher01(self):
        "Contact-user."
        user = self.login()
        report = Report.objects.create(user=user,
                                       name='Fetcher Test',
                                       ct=Organisation)
        graph = ReportGraph.objects.create(
            user=user,
            name='Field Test',
            linked_report=report,
            # abscissa_cell_value='creation_date', abscissa_type=RGT_YEAR,
            abscissa_cell_value='creation_date',
            abscissa_type=ReportGraph.Group.YEAR,
            # ordinate_type=RGA_COUNT,
            ordinate_type=ReportGraph.Aggregator.COUNT,
        )

        url = reverse('reports__create_instance_brick', args=(graph.id, ))
        response = self.assertGET200(url)

        with self.assertNoException():
            choices = [
                *response.context['form'].fields['fetcher'].widget.choices
            ]

        vname = _('Belows to the Contact/User')
        self.assertInChoices(
            value=f'{RGF_OWNED}|',
            label=vname,
            choices=choices,
        )

        self.assertNoFormError(
            self.client.post(url, data={'fetcher': RGF_OWNED}))

        ibci = self.get_object_or_fail(InstanceBrickConfigItem,
                                       entity=graph.id)
        self.assertEqual('instanceblock_reports-graph', ibci.brick_class_id)
        self.assertEqual(RGF_OWNED, ibci.get_extra_data('type'))
        self.assertIsNone(ibci.get_extra_data('value'))

        brick = ReportGraphBrick(ibci)
        self.assertEqual(
            f'{graph.name} - {vname}',
            brick.verbose_name,
        )
        self.assertListEqual([Contact], brick.target_ctypes)

        # Display on detail-view
        create_orga = partial(Organisation.objects.create, user=user)
        create_orga(name='Orga#1',
                    creation_date=date(year=2015, month=1, day=1))
        create_orga(name='Orga#2',
                    creation_date=date(year=2015, month=2, day=2))
        create_orga(
            name='Orga#3',
            creation_date=date(year=2015, month=3, day=3),
            user=self.other_user,
        )
        create_orga(name='Orga#4',
                    creation_date=date(year=2016, month=4, day=4))

        fetcher = brick.fetcher
        self.assertIsInstance(fetcher, OwnedGraphFetcher)
        self.assertIsNone(fetcher.error)
        self.assertEqual(vname, fetcher.verbose_name)

        x, y = fetcher.fetch_4_entity(entity=user.linked_contact, user=user)
        self.assertListEqual(['2015', '2016'], x)

        qfilter_serializer = QSerializer()
        lv_url = reverse('persons__list_organisations')

        def build_url(year):
            return '{}?q_filter={}'.format(
                lv_url,
                qfilter_serializer.dumps(
                    Q(user=user.id) & Q(creation_date__year=year)),
            )

        self.assertListEqual([[2, build_url(2015)], [1, build_url(2016)]], y)

        # ---
        ibci = fetcher.create_brick_config_item()
        BrickDetailviewLocation.objects.create_if_needed(
            brick=ibci.brick_id,
            order=1,
            zone=BrickDetailviewLocation.RIGHT,
            model=Contact,
        )

        contact = user.linked_contact
        response = self.assertGET200(contact.get_absolute_url())
        dom = self.get_html_tree(response.content)
        brick_node = self.get_brick_node(dom, brick_id=ibci.brick_id)
        self.assertBrickHasNotClass(brick_node, 'is-empty')

        volatile_span = brick_node.find(
            './/span[@class="graph-volatile-value"]')
        self.assertIsNotNone(volatile_span)
        self.assertEqual(vname, volatile_span.text)

        # --
        self.assertGET200(
            reverse('reports__fetch_graph_from_brick',
                    args=(ibci.id, contact.id)))
コード例 #23
0
ファイル: listview.py プロジェクト: HybirdCorp/creme_crm-2.0
def list_view_content(
        request,
        model,
        hf_pk='',
        extra_dict=None,
        template='creme_core/generics/list_entities.html',
        show_actions=True,
        extra_q=None,
        mode=MODE_MULTIPLE_SELECTION,
        post_process=None,
        content_template='creme_core/frags/list_view_content.html',
        lv_state_id=None):
    """ Generic list_view wrapper / generator
    Accepts only CremeEntity model and subclasses.
    @param post_process: Function that takes the template context and the
                         request as parameters (so you can modify the context).
    """
    assert issubclass(
        model,
        CremeEntity), '{} is not a subclass of CremeEntity'.format(model)

    PAGE_SIZES = settings.PAGE_SIZES

    is_GET = request.method == 'GET'
    arguments = request.GET if is_GET else request.POST
    lv_state_id = lv_state_id or request.path
    current_lvs = ListViewState.get_or_create_state(request, url=lv_state_id)

    rows = _build_rowscount(arguments, current_lvs)

    transient = is_GET or (arguments.get('transient') in {'1', 'true'})
    ct = ContentType.objects.get_for_model(model)
    user = request.user
    header_filters = HeaderFilterList(ct, user)

    hf = current_lvs.set_headerfilter(header_filters,
                                      arguments.get('hfilter', -1), hf_pk)
    cells = hf.cells

    if show_actions:
        # cells.insert(0, EntityCellActions(model=model))
        cells.insert(
            0, EntityCellActions(model=model,
                                 actions_registry=actions_registry))

    if arguments.get('search', '') == 'clear':
        current_lvs.clear_research()
    else:
        current_lvs.handle_research(arguments, cells, merge=transient)

    entity_filters = EntityFilterList(ct, user)
    efilter = _select_entityfilter(arguments, entity_filters,
                                   current_lvs.entity_filter_id)
    current_lvs.entity_filter_id = efilter.id if efilter else None

    json_q_filter, extra_filter = _build_extrafilter(arguments, extra_q)

    entities, count = _build_entity_queryset(user, model, current_lvs,
                                             extra_filter, efilter, hf)
    fast_mode = (count >= settings.FAST_QUERY_MODE_THRESHOLD)
    ordering = current_lvs.set_sort(
        model,
        cells,
        cell_key=arguments.get('sort_field', current_lvs.sort_field),
        order=arguments.get('sort_order', current_lvs.sort_order),
        fast_mode=fast_mode,
    )

    entities_page = _build_entities_page(
        arguments,
        current_lvs,
        entities.order_by(*ordering),
        size=rows,
        count=count,
        ordering=ordering,
        fast_mode=fast_mode,
    )

    if not transient:
        current_lvs.register_in_session(request)

    template_dict = {
        'model':
        model,
        'list_title':
        _('List of {models}').format(models=model._meta.verbose_name_plural),
        'sub_title':
        '',
        'header_filters':
        header_filters,
        'entity_filters':
        entity_filters,
        'entities':
        entities_page,
        'list_view_state':
        current_lvs,
        'content_type':
        ct,
        'content_type_id':
        ct.id,
        'search':
        len(current_lvs.research) > 0,
        'content_template':
        content_template,
        'page_sizes':
        PAGE_SIZES,
        'o2m': (mode == MODE_SINGLE_SELECTION),
        'add_url':
        model.get_create_absolute_url(),
        'extra_bt_templates':
        None,  # TODO: () instead ???,
        'show_actions':
        show_actions,
        'extra_filter':
        QSerializer().dumps(extra_filter),
        'q_filter':
        json_q_filter,
        'research_cellkeys':
        {cell_key
         for cell_key, _value in current_lvs.research},
        'is_popup_view':
        False,
    }

    if extra_dict:
        template_dict.update(extra_dict)

    if request.is_ajax():
        template = template_dict['content_template']

    if post_process:
        post_process(template_dict, request)

    # Optimisation time !!
    hf.populate_entities(entities_page.object_list, user)

    return template, template_dict