Search code examples
pythondjangopython-3.xunit-testingdjango-2.x

how to dynamicaly create models in tests?


I would like to test my custom subclassed Django model field. I could use existing models from my project but they are quite complicated and hard to setup.

I have found two SO question but the are quite old (2009 and 2012). #1 #2

So I wanted to ask if anyone knows a better way to achieve this. Django wiki has a dedicated page for custom fields, but there I haven't found anything about testing there.

Thanks for any tip or suggestion.


Solution

  • The simplest answer is that you can just declare the class in your code. If all you want to do is test things like initialization or validation, that is enough. In order to create objects in the database, you'll need to add the model to the django registry, and in order to not pollute the registry for other tests run in sequence, you'll want to clear it.

    Documentation on how to handle the registry stuff can be found here. Here's some basic outlined code which is a pared-down version of something I use to test a custom field:

    from django.db import connection
    from django.test import TestCase
    from django.test.utils import isolate_apps
    
    
    class MyFieldTestCase(TestCase):
    
        @isolate_apps('my_app_label')
        def test_my_field(self):
            """Example field test
            """
            class TestModel(models.Model):
                test_field = MySuperCoolFieldClass()
                class Meta:
                    app_label = 'my_app_label'
    
            def cleanup_test_model():
                with connection.schema_editor() as schema_editor:
                    schema_editor.delete_model(TestModel)
    
            with connection.schema_editor() as schema_editor:
                schema_editor.create_model(TestModel)
            self.addCleanup(cleanup_test_model)
    
            # run stuff with your TestModel class