Beispiel #1
0
    def _update_excluded_with_related_not_required(
        cls,
        exclude: Union["AbstractSetIntStr", "MappingIntStrAny", None],
        nested: bool = False,
    ) -> Union[Set, Dict]:
        """
        Used during generation of the dict().
        To avoid cyclical references and max recurrence limit nested models have to
        exclude related models that are not mandatory.

        For a main model (not nested) only nullable related field names are added to
        exclusion, for nested models all related models are excluded.

        :param exclude: set/dict with fields to exclude
        :type exclude: Union[Set, Dict, None]
        :param nested: flag setting nested models (child of previous one, not main one)
        :type nested: bool
        :return: set or dict with excluded fields added.
        :rtype: Union[Set, Dict]
        """
        exclude = exclude or {}
        related_set = cls._exclude_related_names_not_required(nested=nested)
        if isinstance(exclude, set):
            exclude.union(related_set)
        else:
            related_dict = translate_list_to_dict(related_set)
            exclude = update(related_dict, exclude)
        return exclude
Beispiel #2
0
def test_updating_dict_inc_set_with_dict_inc_set():
    curr_dict = {
        "aa": Ellipsis,
        "bb": Ellipsis,
        "cc": {
            "aa": {"xx", "yy"},
            "bb": Ellipsis
        },
    }
    dict_to_update = {
        "uu": Ellipsis,
        "bb": {"cc", "dd"},
        "cc": {
            "aa": {"xx", "oo", "zz", "ii"}
        },
    }
    test = update(curr_dict, dict_to_update)
    assert test == {
        "aa": Ellipsis,
        "bb": {"cc", "dd"},
        "cc": {
            "aa": {"xx", "yy", "oo", "zz", "ii"},
            "bb": Ellipsis
        },
        "uu": Ellipsis,
    }
Beispiel #3
0
 def _update_excluded_with_related_not_required(
     cls,
     exclude: Union["AbstractSetIntStr", "MappingIntStrAny", None],
     nested: bool = False,
 ) -> Union[Set, Dict]:
     exclude = exclude or {}
     related_set = cls._exclude_related_names_not_required(nested=nested)
     if isinstance(exclude, set):
         exclude.union(related_set)
     else:
         related_dict = translate_list_to_dict(related_set)
         exclude = update(related_dict, exclude)
     return exclude
Beispiel #4
0
    def exclude_fields(self, columns: Union[List, str, Set,
                                            Dict]) -> "QuerySet":
        """
        With `exclude_fields()` you can select subset of model columns that will
        be excluded to limit the data load.

        It's the opposite of `fields()` method so check documentation above
        to see what options are available.

        Especially check above how you can pass also nested dictionaries
        and sets as a mask to exclude fields from whole hierarchy.

        Note that `fields()` and `exclude_fields()` works both for main models
        (on normal queries like `get`, `all` etc.)
        as well as `select_related` and `prefetch_related` models
        (with nested notation).

        Mandatory fields cannot be excluded as it will raise `ValidationError`,
        to exclude a field it has to be nullable.

        Pk column cannot be excluded - it's always auto added even
        if explicitly excluded.

        :param columns: columns to exclude
        :type columns: Union[List, str, Set, Dict]
        :return: QuerySet
        :rtype: QuerySet
        """
        if isinstance(columns, str):
            columns = [columns]

        current_excluded = self._exclude_columns
        if not isinstance(columns, dict):
            current_excluded = update_dict_from_list(current_excluded, columns)
        else:
            current_excluded = update(current_excluded, columns)

        return self.__class__(
            model_cls=self.model,
            filter_clauses=self.filter_clauses,
            exclude_clauses=self.exclude_clauses,
            select_related=self._select_related,
            limit_count=self.limit_count,
            offset=self.query_offset,
            columns=self._columns,
            exclude_columns=current_excluded,
            order_bys=self.order_bys,
            prefetch_related=self._prefetch_related,
            limit_raw_sql=self.limit_sql_raw,
        )
Beispiel #5
0
    def fields(self, columns: Union[List, str, Set, Dict]) -> "QuerySet":
        if isinstance(columns, str):
            columns = [columns]

        current_included = self._columns
        if not isinstance(columns, dict):
            current_included = update_dict_from_list(current_included, columns)
        else:
            current_included = update(current_included, columns)

        return self.__class__(
            model_cls=self.model,
            filter_clauses=self.filter_clauses,
            exclude_clauses=self.exclude_clauses,
            select_related=self._select_related,
            limit_count=self.limit_count,
            offset=self.query_offset,
            columns=current_included,
            exclude_columns=self._exclude_columns,
            order_bys=self.order_bys,
        )
Beispiel #6
0
    def fields(self, columns: Union[List, str, Set, Dict]) -> "QuerySet":
        """
        With `fields()` you can select subset of model columns to limit the data load.

        Note that `fields()` and `exclude_fields()` works both for main models
        (on normal queries like `get`, `all` etc.)
        as well as `select_related` and `prefetch_related`
        models (with nested notation).

        You can select specified fields by passing a `str, List[str], Set[str] or
        dict` with nested definition.

        To include related models use notation
        `{related_name}__{column}[__{optional_next} etc.]`.

        `fields()` can be called several times, building up the columns to select.

        If you include related models into `select_related()` call but you won't specify
        columns for those models in fields - implies a list of all fields for
        those nested models.

        Mandatory fields cannot be excluded as it will raise `ValidationError`,
        to exclude a field it has to be nullable.

        Pk column cannot be excluded - it's always auto added even if
        not explicitly included.

        You can also pass fields to include as dictionary or set.

        To mark a field as included in a dictionary use it's name as key
        and ellipsis as value.

        To traverse nested models use nested dictionaries.

        To include fields at last level instead of nested dictionary a set can be used.

        To include whole nested model specify model related field name and ellipsis.

        :param columns: columns to include
        :type columns: Union[List, str, Set, Dict]
        :return: QuerySet
        :rtype: QuerySet
        """
        if isinstance(columns, str):
            columns = [columns]

        current_included = self._columns
        if not isinstance(columns, dict):
            current_included = update_dict_from_list(current_included, columns)
        else:
            current_included = update(current_included, columns)

        return self.__class__(
            model_cls=self.model,
            filter_clauses=self.filter_clauses,
            exclude_clauses=self.exclude_clauses,
            select_related=self._select_related,
            limit_count=self.limit_count,
            offset=self.query_offset,
            columns=current_included,
            exclude_columns=self._exclude_columns,
            order_bys=self.order_bys,
            prefetch_related=self._prefetch_related,
            limit_raw_sql=self.limit_sql_raw,
        )