mirror of
				https://github.com/django/django.git
				synced 2025-11-04 05:35:37 +00:00 
			
		
		
		
	Improved validation of swappable model settings.
This commit is contained in:
		
							parent
							
								
									5a04cde342
								
							
						
					
					
						commit
						6494bf91f2
					
				
					 4 changed files with 41 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -97,7 +97,10 @@ def get_user_model():
 | 
			
		|||
    from django.conf import settings
 | 
			
		||||
    from django.db.models import get_model
 | 
			
		||||
 | 
			
		||||
    app_label, model_name = settings.AUTH_USER_MODEL.split('.')
 | 
			
		||||
    try:
 | 
			
		||||
        app_label, model_name = settings.AUTH_USER_MODEL.split('.')
 | 
			
		||||
    except ValueError:
 | 
			
		||||
        raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form 'app_label.model_name'")
 | 
			
		||||
    return get_model(app_label, model_name)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -285,6 +285,16 @@ def get_validation_errors(outfile, app=None):
 | 
			
		|||
                    if r.get_accessor_name() == rel_query_name:
 | 
			
		||||
                        e.add(opts, "Reverse query name for m2m field '%s' clashes with related field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name))
 | 
			
		||||
 | 
			
		||||
        # Check swappable attribute.
 | 
			
		||||
        if opts.swapped:
 | 
			
		||||
            try:
 | 
			
		||||
                app_label, model_name = opts.swapped.split('.')
 | 
			
		||||
            except ValueError:
 | 
			
		||||
                e.add(opts, "%s is not of the form 'app_label.app_name'." % opts.swappable)
 | 
			
		||||
                continue
 | 
			
		||||
            if not models.get_model(app_label, model_name):
 | 
			
		||||
                e.add(opts, "Model has been swapped out for '%s' which has not been installed or is abstract." % opts.swapped)
 | 
			
		||||
 | 
			
		||||
        # Check ordering attribute.
 | 
			
		||||
        if opts.ordering:
 | 
			
		||||
            for field_name in opts.ordering:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -310,6 +310,26 @@ class SwappedModel(models.Model):
 | 
			
		|||
        swappable = 'TEST_SWAPPED_MODEL'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BadSwappableValue(models.Model):
 | 
			
		||||
    """A model that can be swapped out; during testing, the swappable
 | 
			
		||||
    value is not of the format app.model
 | 
			
		||||
    """
 | 
			
		||||
    name = models.CharField(max_length=100)
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        swappable = 'TEST_SWAPPED_MODEL_BAD_VALUE'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BadSwappableModel(models.Model):
 | 
			
		||||
    """A model that can be swapped out; during testing, the swappable
 | 
			
		||||
    value references an unknown model.
 | 
			
		||||
    """
 | 
			
		||||
    name = models.CharField(max_length=100)
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        swappable = 'TEST_SWAPPED_MODEL_BAD_MODEL'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HardReferenceModel(models.Model):
 | 
			
		||||
    fk_1 = models.ForeignKey(SwappableModel, related_name='fk_hardref1')
 | 
			
		||||
    fk_2 = models.ForeignKey('invalid_models.SwappableModel', related_name='fk_hardref2')
 | 
			
		||||
| 
						 | 
				
			
			@ -433,6 +453,8 @@ invalid_models.hardreferencemodel: 'fk_3' defines a relation with the model 'inv
 | 
			
		|||
invalid_models.hardreferencemodel: 'fk_4' defines a relation with the model 'invalid_models.SwappedModel', which has been swapped out. Update the relation to point at settings.TEST_SWAPPED_MODEL.
 | 
			
		||||
invalid_models.hardreferencemodel: 'm2m_3' defines a relation with the model 'invalid_models.SwappedModel', which has been swapped out. Update the relation to point at settings.TEST_SWAPPED_MODEL.
 | 
			
		||||
invalid_models.hardreferencemodel: 'm2m_4' defines a relation with the model 'invalid_models.SwappedModel', which has been swapped out. Update the relation to point at settings.TEST_SWAPPED_MODEL.
 | 
			
		||||
invalid_models.badswappablevalue: TEST_SWAPPED_MODEL_BAD_VALUE is not of the form 'app_label.app_name'.
 | 
			
		||||
invalid_models.badswappablemodel: Model has been swapped out for 'not_an_app.Target' which has not been installed or is abstract.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
if not connection.features.interprets_empty_strings_as_nulls:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,11 @@ class InvalidModelTestCase(unittest.TestCase):
 | 
			
		|||
    # set to *something* in order for the test to work. However, it's
 | 
			
		||||
    # easier to set this up as an override than to require every developer
 | 
			
		||||
    # to specify a value in their test settings.
 | 
			
		||||
    @override_settings(TEST_SWAPPED_MODEL='invalid_models.Target')
 | 
			
		||||
    @override_settings(
 | 
			
		||||
        TEST_SWAPPED_MODEL='invalid_models.Target',
 | 
			
		||||
        TEST_SWAPPED_MODEL_BAD_VALUE='not-a-model',
 | 
			
		||||
        TEST_SWAPPED_MODEL_BAD_MODEL='not_an_app.Target',
 | 
			
		||||
    )
 | 
			
		||||
    def test_invalid_models(self):
 | 
			
		||||
        try:
 | 
			
		||||
            module = load_app("modeltests.invalid_models.invalid_models")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue