Code

Opened 2 years ago

Closed 2 years ago

#17394 closed Uncategorized (invalid)

Models in a package breaks model validation

Reported by: Wilfred Hughes <wilfred@…> Owned by: nobody
Component: Database layer (models, ORM) Version: 1.3
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

If I create an app:

$ ./manage.py startapp test_app

I then create a package for my models:

$ cd test_app
$ mkdir models
$ cd models
$ touch __init__.py

I then create an invalid model in test_app/models/bar.py:

from django.db import models

class Foo(models.Model):
    class Meta:
        app_label = 'test_app.models'
    
    invalid_char_field = models.CharField() # should have max_length

Finally, I import this in my tests, I chose test_app/tests.py:

from django.test import TestCase
from models.bar import Bar

class SimpleTest(TestCase):
    def test_basic_addition(self):
        """
        Tests that 1 + 1 always equals 2.
        """
        self.assertEqual(1 + 1, 2)

This has a really weird effect on model validation. Calling validate works:

$ ./manage.py validate
0 errors found

But tests seem to have a different validation path, and fail as expected:

$ ./manage.py test test_app
Creating test database for alias 'default'...
Error: One or more models did not validate:
test_app.foo: "invalid_char_field": CharFields require a "max_length" attribute that is a positive integer.

I know this isn't a common use case, but I have an old project that has models like this. #2289 suggests I should be able to do this. I can work around it by adding an import for every single model in test_app/models/*.py inside of test_app/__init__.py but that introduces name clashes.

Thanks.

Attachments (0)

Change History (6)

comment:1 Changed 2 years ago by anonymous

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to needsinfo
  • Status changed from new to closed

What happens when you use a correct value for app_label?:

class Foo(models.Model):
    class Meta:
        app_label = 'test_app'

comment:2 Changed 2 years ago by Wilfred Hughes <wilfred@…>

  • Resolution needsinfo deleted
  • Status changed from closed to reopened

Ah, sorry. Behaviour is exactly the same with the correct value for app_label.

comment:3 Changed 2 years ago by charettes

Did you remove the models.py file created by the startapp command?

comment:4 Changed 2 years ago by Wilfred Hughes <wilfred@…>

I did, but the behaviour is the same both with and without test_app/models.py.

comment:5 Changed 2 years ago by charettes

What happens if you put from bar import * in your models/__init__.py file?

comment:6 Changed 2 years ago by aaugustin

  • Resolution set to invalid
  • Status changed from reopened to closed

As pointed out in charettes' latest comment, the problem is that your model isn't detected by validate, because it isn't imported in the test_app.models package.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.