Example #1
0
    def _check_mysql_version(self):
        errors = []

        any_conn_works = False
        for _alias, conn in mysql_connections():
            if (hasattr(conn, "mysql_version")
                    and not connection_is_mariadb(conn)
                    and conn.mysql_version >= (5, 7)):
                any_conn_works = True

        if not any_conn_works:
            errors.append(
                checks.Error(
                    "MySQL 5.7+ is required to use JSONField",
                    hint="At least one of your DB connections should be to "
                    "MySQL 5.7+",
                    obj=self,
                    id="django_mysql.E016",
                ))
        return errors
Example #2
0
    def test_check_unique_sf_field_names(self):
        class MyModel(hc_models.HerokuConnectModel):
            sf_object_name = "My_Object__c"
            date1 = hc_models.DateTime(sf_field_name="Date1__c",
                                       db_column="date1")
            date2 = hc_models.DateTime(sf_field_name="Date1__c",
                                       db_column="date2")

            class Meta:
                app_label = "test"
                abstract = True

        errors = MyModel.check()
        assert errors == [
            checks.Error(
                "test.MyModel has duplicate Salesforce field names.",
                hint=["Date1__c"],
                id="heroku_connect.E003",
            )
        ]
Example #3
0
    def test_content_type_field_pointing_to_wrong_model(self):
        class Model(models.Model):
            content_type = models.ForeignKey('self', models.CASCADE)  # should point to ContentType
            object_id = models.PositiveIntegerField()
            content_object = GenericForeignKey(
                'content_type', 'object_id')

        errors = Model.content_object.check()
        expected = [
            checks.Error(
                "'Model.content_type' is not a ForeignKey to 'contenttypes.ContentType'.",
                hint=(
                    "GenericForeignKeys must use a ForeignKey to "
                    "'contenttypes.ContentType' as the 'content_type' field."
                ),
                obj=Model.content_object,
                id='contenttypes.E004',
            )
        ]
        self.assertEqual(errors, expected)
Example #4
0
    def _check_mariadb_version(self):
        errors = []

        any_conn_works = False
        conn_names = ['default'] + list(set(connections) - {'default'})
        for db in conn_names:
            conn = connections[db]
            if (hasattr(conn, 'mysql_version') and connection_is_mariadb(conn)
                    and conn.mysql_version >= (10, 0, 1)):
                any_conn_works = True

        if not any_conn_works:
            errors.append(
                checks.Error(
                    'MariaDB 10.0.1+ is required to use DynamicField',
                    hint='At least one of your DB connections should be to '
                    'MariaDB 10.0.1+',
                    obj=self,
                    id='django_mysql.E013'))
        return errors
Example #5
0
    def test_generic_inline_model_admin_bad_fk_field(self):
        "A GenericInlineModelAdmin raises problems if the ct_fk_field points to a non-existent field."

        class InfluenceInline(GenericStackedInline):
            model = Influence
            ct_fk_field = 'nonexistent'

        class SongAdmin(admin.ModelAdmin):
            inlines = [InfluenceInline]

        errors = SongAdmin.check(model=Song)
        expected = [
            checks.Error(
                "'ct_fk_field' references 'nonexistent', which is not a field on 'admin_checks.Influence'.",
                hint=None,
                obj=InfluenceInline,
                id='admin.E303',
            )
        ]
        self.assertEqual(errors, expected)
Example #6
0
    def test_required_fields_is_list(self):
        """REQUIRED_FIELDS should be a list."""
        class CustomUserNonListRequiredFields(AbstractBaseUser):
            username = models.CharField(max_length=30, unique=True)
            date_of_birth = models.DateField()

            USERNAME_FIELD = "username"
            REQUIRED_FIELDS = "date_of_birth"

        errors = checks.run_checks(app_configs=self.apps.get_app_configs())
        self.assertEqual(
            errors,
            [
                checks.Error(
                    "'REQUIRED_FIELDS' must be a list or tuple.",
                    obj=CustomUserNonListRequiredFields,
                    id="auth.E001",
                ),
            ],
        )
Example #7
0
    def _check_mysql_version(self):
        errors = []

        any_conn_works = False
        for alias, conn in mysql_connections():
            if (hasattr(conn, 'mysql_version')
                    and not connection_is_mariadb(conn)
                    and conn.mysql_version >= (5, 7)):
                any_conn_works = True

        if not any_conn_works:
            errors.append(
                checks.Error(
                    'MySQL 5.7+ is required to use JSONField',
                    hint='At least one of your DB connections should be to '
                    'MySQL 5.7+',
                    obj=self,
                    id='django_mysql.E016',
                ), )
        return errors
Example #8
0
    def test_missing_generic_foreign_key(self):
        class TaggedItem(models.Model):
            content_type = models.ForeignKey(ContentType, models.CASCADE)
            object_id = models.PositiveIntegerField()

        class Bookmark(models.Model):
            tags = GenericRelation("TaggedItem")

        self.assertEqual(
            Bookmark.tags.field.check(),
            [
                checks.Error(
                    "The GenericRelation defines a relation with the model "
                    "'contenttypes_tests.TaggedItem', but that model does not have a "
                    "GenericForeignKey.",
                    obj=Bookmark.tags.field,
                    id="contenttypes.E004",
                )
            ],
        )
Example #9
0
 def _check_object_id_field(self):
     target = self.rel.to
     if isinstance(target, ModelBase):
         opts = target._meta
         try:
             opts.get_field(self.object_id_field_name)
         except FieldDoesNotExist:
             return [
                 checks.Error(
                     'The field refers to %s.%s field which is missing.' %
                     (opts.object_name, self.object_id_field_name),
                     hint=None,
                     obj=self,
                     id='contenttypes.E003',
                 )
             ]
         else:
             return []
     else:
         return []
Example #10
0
    def test_missing_generic_foreign_key(self):
        class TaggedItem(models.Model):
            content_type = models.ForeignKey(ContentType)
            object_id = models.PositiveIntegerField()

        class Bookmark(models.Model):
            tags = GenericRelation('TaggedItem')

        errors = Bookmark.tags.field.check()
        expected = [
            checks.Error(
                ("The GenericRelation defines a relation with the model "
                 "'contenttypes_tests.TaggedItem', but that model does not have a "
                 "GenericForeignKey."),
                hint=None,
                obj=Bookmark.tags.field,
                id='contenttypes.E004',
            )
        ]
        self.assertEqual(errors, expected)
Example #11
0
    def test_generic_inline_model_admin_non_generic_model(self):
        """
        A model without a GenericForeignKey raises problems if it's included
        in a GenericInlineModelAdmin definition.
        """
        class BookInline(GenericStackedInline):
            model = Book

        class SongAdmin(admin.ModelAdmin):
            inlines = [BookInline]

        errors = SongAdmin(Song, AdminSite()).check()
        expected = [
            checks.Error(
                "'admin_checks.Book' has no GenericForeignKey.",
                obj=BookInline,
                id='admin.E301',
            )
        ]
        self.assertEqual(errors, expected)
Example #12
0
    def test_new_fields(self):
        class NoNewFields(Person):
            newfield = models.BooleanField()

            class Meta:
                proxy = True
                # don't register this model in the app_cache for the current app,
                # otherwise the check fails when other tests are being run.
                app_label = 'no_such_app'

        errors = NoNewFields.check()
        expected = [
            checks.Error(
                "Proxy model 'NoNewFields' contains model fields.",
                hint=None,
                obj=None,
                id='models.E017',
            )
        ]
        self.assertEqual(errors, expected)
Example #13
0
    def test_CommaSeparatedIntegerField_deprecated(self):
        class CommaSeparatedIntegerModel(models.Model):
            csi = models.CommaSeparatedIntegerField(max_length=64)

        model = CommaSeparatedIntegerModel()
        self.assertEqual(
            model.check(),
            [
                checks.Error(
                    "CommaSeparatedIntegerField is removed except for support in "
                    "historical migrations.",
                    hint=
                    ("Use "
                     "CharField(validators=[validate_comma_separated_integer_list]) "
                     "instead."),
                    obj=CommaSeparatedIntegerModel._meta.get_field("csi"),
                    id="fields.E901",
                )
            ],
        )
Example #14
0
    def test_user_specified_details(self):
        class MyField(models.Field):
            system_check_removed_details = {
                'msg': 'Support for this field is gone.',
                'hint': 'Use something else.',
                'id': 'fields.E999',
            }

        class Model(models.Model):
            name = MyField()

        model = Model()
        self.assertEqual(model.check(), [
            checks.Error(
                msg='Support for this field is gone.',
                hint='Use something else.',
                obj=Model._meta.get_field('name'),
                id='fields.E999',
            )
        ])
Example #15
0
def check_subscriber_key_length(app_configs=None, **kwargs):
    """
    Check that DJSTRIPE_SUBSCRIBER_CUSTOMER_KEY fits in metadata.

    Docs: https://stripe.com/docs/api#metadata
    """
    from . import settings as djstripe_settings

    messages = []

    key = djstripe_settings.SUBSCRIBER_CUSTOMER_KEY
    key_size = len(str(key))
    if key and key_size > 40:
        messages.append(
            checks.Error(
                "DJSTRIPE_SUBSCRIBER_CUSTOMER_KEY must be no more than 40 characters long",
                hint="Current value: %r (%i characters)" % (key, key_size),
                id="djstripe.E001"))

    return messages
Example #16
0
    def test_check_unique_sf_field_names(self):
        class MyModel(hc_models.HerokuConnectModel):
            sf_object_name = 'My_Object__c'
            date1 = hc_models.DateTime(sf_field_name='Date1__c',
                                       db_column='date1')
            date2 = hc_models.DateTime(sf_field_name='Date1__c',
                                       db_column='date2')

            class Meta:
                app_label = 'test'
                abstract = True

        errors = MyModel.check()
        assert errors == [
            checks.Error(
                "test.MyModel has duplicate Salesforce field names.",
                hint=['Date1__c'],
                id='heroku_connect.E003',
            )
        ]
Example #17
0
 def _check_default(self, **kwargs):
     try:
         default = self.get_default()
         self.enum(default)
         return []
     except ValueError:
         return [
             checks.Error(
                 FieldErrors.E02.display.format(
                     cls=self.__class__.__name__,
                     default=default,
                     enum=self.enum,
                 ),
                 obj=self,
                 id=FieldErrors.E02,
                 hint=_(
                     'Add an enum item with `{0!r}` as value, eg.: `UNDEFINED = {0!r}`, '
                     'or inform a valid default value.').format(default),
             )
         ]
Example #18
0
    def test_verbose_name_max_length(self):
        class Checked(models.Model):
            class Meta:
                verbose_name = (
                    "some ridiculously long verbose name that is out of control"
                    * 5)

        errors = checks.run_checks(self.apps.get_app_configs())
        self.assertEqual(
            errors,
            [
                checks.Error(
                    "The verbose_name of model 'auth_tests.Checked' must be at most "
                    "244 characters for its builtin permission names to be at most 255 "
                    "characters.",
                    obj=Checked,
                    id="auth.E007",
                ),
            ],
        )
Example #19
0
    def test_generic_inline_model_admin_non_gfk_fk_field(self):
        "A GenericInlineModelAdmin raises problems if the ct_fk_field points to a field that isn't part of a GenericForeignKey"

        class InfluenceInline(GenericStackedInline):
            model = Influence
            ct_fk_field = 'name'

        class SongAdmin(admin.ModelAdmin):
            inlines = [InfluenceInline]

        errors = SongAdmin.check(model=Song)
        expected = [
            checks.Error(
                "'admin_checks.Influence' has no GenericForeignKey using content type field 'content_type' and object ID field 'name'.",
                hint=None,
                obj=InfluenceInline,
                id='admin.E304',
            )
        ]
        self.assertEqual(errors, expected)
 def _check_supported(self, databases):
     errors = []
     for db in databases:
         if not router.allow_migrate_model(db, self.model):
             continue
         connection = connections[db]
         if (self.model._meta.required_db_vendor and
                 self.model._meta.required_db_vendor != connection.vendor):
             continue
         if not ('supports_json_field'
                 in self.model._meta.required_db_features
                 or connection.features.supports_json_field):
             errors.append(
                 checks.Error(
                     '%s does not support JSONFields.' %
                     connection.display_name,
                     obj=self.model,
                     id='fields.E180',
                 ))
     return errors
Example #21
0
    def _check_exclude(self, obj):
        """ Check that exclude is a sequence without duplicates. """

        if obj.exclude is None:  # default value is None
            return []
        elif not isinstance(obj.exclude, (list, tuple)):
            return must_be('a list or tuple',
                           option='exclude',
                           obj=obj,
                           id='admin.E014')
        elif len(obj.exclude) > len(set(obj.exclude)):
            return [
                checks.Error(
                    "The value of 'exclude' contains duplicate field(s).",
                    obj=obj.__class__,
                    id='admin.E015',
                )
            ]
        else:
            return []
Example #22
0
    def test_invalid_content_type_field(self):
        class Model(models.Model):
            content_type = models.IntegerField()  # should be ForeignKey
            object_id = models.PositiveIntegerField()
            content_object = GenericForeignKey(
                'content_type', 'object_id')

        errors = Model.content_object.check()
        expected = [
            checks.Error(
                "'Model.content_type' is not a ForeignKey.",
                hint=(
                    "GenericForeignKeys must use a ForeignKey to "
                    "'contenttypes.ContentType' as the 'content_type' field."
                ),
                obj=Model.content_object,
                id='contenttypes.E003',
            )
        ]
        self.assertEqual(errors, expected)
Example #23
0
 def test_readonly_and_editable(self):
     class SongAdmin(admin.ModelAdmin):
         readonly_fields = ["original_release"]
         list_display = ["pk", "original_release"]
         list_editable = ["original_release"]
         fieldsets = [
             (None, {
                 "fields": ["title", "original_release"],
             }),
         ]
     errors = SongAdmin(Song, AdminSite()).check()
     expected = [
         checks.Error(
             "The value of 'list_editable[0]' refers to 'original_release', "
             "which is not editable through the admin.",
             obj=SongAdmin,
             id='admin.E125',
         )
     ]
     self.assertEqual(errors, expected)
Example #24
0
    def _check_model(cls):
        errors = super()._check_model()

        _will_check_abstract_method = cls.__dict__.get(
            '_will_check_abstract_method', True)
        if _will_check_abstract_method and not cls._meta.abstract:
            model_functions = filter(
                callable, map(lambda attr: getattr(cls, attr, None), dir(cls)))
            abstract_functions = filter(
                lambda func: getattr(func, '__isabstractmethod__', False),
                model_functions)
            for abstract_function in abstract_functions:
                errors.append(
                    checks.Error(
                        "'%s' is abstracted but not implemented." %
                        (abstract_function.__name__),
                        obj=cls,
                    ))

        return errors
Example #25
0
 def _check_generic_foreign_key_existence(self):
     target = self.remote_field.model
     if isinstance(target, ModelBase):
         fields = target._meta.private_fields
         if any(
                 self._is_matching_generic_foreign_key(field)
                 for field in fields):
             return []
         else:
             return [
                 checks.Error(
                     "The GenericRelation defines a relation with the model "
                     "'%s.%s', but that model does not have a GenericForeignKey."
                     % (target._meta.app_label, target._meta.object_name),
                     obj=self,
                     id='contenttypes.E004',
                 )
             ]
     else:
         return []
Example #26
0
    def test_username_not_in_required_fields(self, apps):
        """USERNAME_FIELD should not appear in REQUIRED_FIELDS."""
        class CustomUserBadRequiredFields(AbstractBaseUser):
            username = models.CharField(max_length=30, unique=True)
            date_of_birth = models.DateField()

            USERNAME_FIELD = 'username'
            REQUIRED_FIELDS = ['username', 'date_of_birth']

        errors = checks.run_checks(apps.get_app_configs())
        expected = [
            checks.Error(
                ("The field named as the 'USERNAME_FIELD' for a custom user model "
                 "must not be included in 'REQUIRED_FIELDS'."),
                hint=None,
                obj=CustomUserBadRequiredFields,
                id='auth.E002',
            ),
        ]
        self.assertEqual(errors, expected)
Example #27
0
    def test_invalid_content_type_field(self):
        class Model(models.Model):
            content_type = models.IntegerField()  # should be ForeignKey
            object_id = models.PositiveIntegerField()
            content_object = GenericForeignKey("content_type", "object_id")

        self.assertEqual(
            Model.content_object.check(),
            [
                checks.Error(
                    "'Model.content_type' is not a ForeignKey.",
                    hint=(
                        "GenericForeignKeys must use a ForeignKey to "
                        "'contenttypes.ContentType' as the 'content_type' field."
                    ),
                    obj=Model.content_object,
                    id="contenttypes.E003",
                )
            ],
        )
Example #28
0
    def test_graceful_m2m_fail(self):
        """
        Regression test for #12203/#12237 - Fail more gracefully when a M2M field that
        specifies the 'through' option is included in the 'fields' or the 'fieldsets'
        ModelAdmin options.
        """
        class BookAdmin(admin.ModelAdmin):
            fields = ['authors']

        errors = BookAdmin.check(model=Book)
        expected = [
            checks.Error(
                ('"fields" cannot include the ManyToManyField "authors", '
                 'because "authors" manually specifies relationship model.'),
                hint=None,
                obj=BookAdmin,
                id='admin.E013',
            )
        ]
        self.assertEqual(errors, expected)
Example #29
0
    def test_username_partially_unique(self):
        class CustomUserPartiallyUnique(AbstractBaseUser):
            username = models.CharField(max_length=30)
            USERNAME_FIELD = "username"

            class Meta:
                constraints = [
                    UniqueConstraint(
                        fields=["username"],
                        name="partial_username_unique",
                        condition=Q(password__isnull=False),
                    ),
                ]

        errors = checks.run_checks(app_configs=self.apps.get_app_configs())
        self.assertEqual(
            errors,
            [
                checks.Error(
                    "'CustomUserPartiallyUnique.username' must be unique because "
                    "it is named as the 'USERNAME_FIELD'.",
                    obj=CustomUserPartiallyUnique,
                    id="auth.E003",
                ),
            ],
        )
        with self.settings(AUTHENTICATION_BACKENDS=["my.custom.backend"]):
            errors = checks.run_checks(app_configs=self.apps.get_app_configs())
            self.assertEqual(
                errors,
                [
                    checks.Warning(
                        "'CustomUserPartiallyUnique.username' is named as the "
                        "'USERNAME_FIELD', but it is not unique.",
                        hint=("Ensure that your authentication backend(s) can "
                              "handle non-unique usernames."),
                        obj=CustomUserPartiallyUnique,
                        id="auth.W004",
                    ),
                ],
            )
Example #30
0
    def test_cannot_include_through(self):
        class FieldsetBookAdmin(admin.ModelAdmin):
            fieldsets = (
                ('Header 1', {
                    'fields': ('name', )
                }),
                ('Header 2', {
                    'fields': ('authors', )
                }),
            )

        errors = FieldsetBookAdmin(Book, AdminSite()).check()
        expected = [
            checks.Error(
                "The value of 'fieldsets[1][1][\"fields\"]' cannot include the ManyToManyField "
                "'authors', because that field manually specifies a relationship model.",
                obj=FieldsetBookAdmin,
                id='admin.E013',
            )
        ]
        self.assertEqual(errors, expected)