Exemplo n.º 1
0
    def __init__(self, item_field_type, *args, **kwargs):

        # This seems bonkers, we shout at people for specifying null=True, but then do it ourselves. But this is because
        # *we* abuse None values for our own purposes (to represent an empty iterable) if someone else tries to then
        # all hell breaks loose
        if kwargs.get("null", False):
            raise RuntimeError(
                "IterableFields cannot be set as nullable (as the datastore doesn't differentiate None vs []"
            )

        kwargs["null"] = True

        default = kwargs.get("default", [])

        self._original_item_field_type = copy.deepcopy(
            item_field_type)  # For deconstruction purposes

        if default is not None and not callable(default):
            kwargs["default"] = lambda: self._iterable_type(default)

        if hasattr(item_field_type, 'attname'):
            item_field_type = item_field_type.__class__

        if callable(item_field_type):
            item_field_type = item_field_type()

        if isinstance(item_field_type, models.ForeignKey):
            raise ImproperlyConfigured(
                "Lists of ForeignKeys aren't supported, use RelatedSetField instead"
            )

        self.item_field_type = item_field_type

        # We'll be pretending that item_field is a field of a model
        # with just one "value" field.
        assert not hasattr(self.item_field_type, 'attname')
        self.item_field_type.set_attributes_from_name('value')

        # Pop the 'min_length' and 'max_length' from the kwargs, if they're there, as this avoids
        # 'min_length' causing an error when calling super()
        min_length = kwargs.pop("min_length", None)
        max_length = kwargs.pop("max_length", None)

        # Check that if there's a min_length that blank is not True.  This is partly because it
        # doesn't make sense, and partly because if the value (i.e. the list or set) is empty then
        # Django will skip the validators, thereby skipping the min_length check.
        if min_length and kwargs.get("blank"):
            raise ImproperlyConfigured(
                "Setting blank=True and min_length=%d is contradictory." %
                min_length)

        super(IterableField, self).__init__(*args, **kwargs)

        # Now that self.validators has been set up, we can add the min/max legnth validators
        if min_length is not None:
            self.validators.append(MinItemsValidator(min_length))
        if max_length is not None:
            self.validators.append(MaxItemsValidator(max_length))
Exemplo n.º 2
0
    def __init__(self,
                 to,
                 limit_choices_to=None,
                 related_name=None,
                 on_delete=models.DO_NOTHING,
                 **kwargs):
        # Make sure that we do nothing on cascade by default
        self._check_sane_on_delete_value(on_delete)

        from_fields = ['self']
        to_fields = [None]

        min_length, max_length = self._sanitize_min_and_max_length(kwargs)

        if django.VERSION[1] == 8:
            # in Django 1.8 ForeignObject uses get_lookup_constraint instead
            # of get_lookup. We want to override it (but only for Django 1.8)
            self.get_lookup_constraint = self._get_lookup_constraint

            # Django 1.8 doesn't support the rel_class attribute so we have to pass it up
            # manually.
            kwargs["rel"] = self.rel_class(
                self,
                to,
                related_name=related_name,
                related_query_name=kwargs.get("related_query_name"),
                limit_choices_to=limit_choices_to,
                parent_link=kwargs.get("parent_link"),
                on_delete=on_delete)

            super(RelatedIteratorField, self).__init__(to, from_fields,
                                                       to_fields, **kwargs)
        else:
            super(RelatedIteratorField,
                  self).__init__(to,
                                 on_delete,
                                 from_fields,
                                 to_fields,
                                 related_name=related_name,
                                 limit_choices_to=limit_choices_to,
                                 **kwargs)

        # Now that self.validators has been set up, we can add the min/max legnth validators
        if min_length is not None:
            self.validators.append(MinItemsValidator(min_length))
        if max_length is not None:
            self.validators.append(MaxItemsValidator(max_length))