mirror of
				https://github.com/django/django.git
				synced 2025-10-30 17:16:10 +00:00 
			
		
		
		
	[1.7.x] Fixed #22514 -- Prevented indexes on virtual fields [postgres].
Backport of 78c32f1caa from master
			
			
This commit is contained in:
		
				
					committed by
					
						 Tim Graham
						Tim Graham
					
				
			
			
				
	
			
			
			
						parent
						
							d9a83d597e
						
					
				
				
					commit
					6e5a736752
				
			| @@ -47,7 +47,8 @@ class DatabaseCreation(BaseDatabaseCreation): | |||||||
|  |  | ||||||
|     def sql_indexes_for_field(self, model, f, style): |     def sql_indexes_for_field(self, model, f, style): | ||||||
|         output = [] |         output = [] | ||||||
|         if f.db_index or f.unique: |         db_type = f.db_type(connection=self.connection) | ||||||
|  |         if db_type is not None and (f.db_index or f.unique): | ||||||
|             qn = self.connection.ops.quote_name |             qn = self.connection.ops.quote_name | ||||||
|             db_table = model._meta.db_table |             db_table = model._meta.db_table | ||||||
|             tablespace = f.db_tablespace or model._meta.db_tablespace |             tablespace = f.db_tablespace or model._meta.db_tablespace | ||||||
| @@ -73,7 +74,6 @@ class DatabaseCreation(BaseDatabaseCreation): | |||||||
|             # a second index that specifies their operator class, which is |             # a second index that specifies their operator class, which is | ||||||
|             # needed when performing correct LIKE queries outside the |             # needed when performing correct LIKE queries outside the | ||||||
|             # C locale. See #12234. |             # C locale. See #12234. | ||||||
|             db_type = f.db_type(connection=self.connection) |  | ||||||
|             if db_type.startswith('varchar'): |             if db_type.startswith('varchar'): | ||||||
|                 output.append(get_index_sql('%s_%s_like' % (db_table, f.column), |                 output.append(get_index_sql('%s_%s_like' % (db_table, f.column), | ||||||
|                                             ' varchar_pattern_ops')) |                                             ' varchar_pattern_ops')) | ||||||
|   | |||||||
| @@ -2,10 +2,35 @@ from django.db import connection | |||||||
| from django.db import models | from django.db import models | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class CurrentTranslation(models.ForeignObject): | ||||||
|  |     """ | ||||||
|  |     Creates virtual relation to the translation with model cache enabled. | ||||||
|  |     """ | ||||||
|  |     # Avoid validation | ||||||
|  |     requires_unique_target = False | ||||||
|  |  | ||||||
|  |     def __init__(self, to, from_fields, to_fields, **kwargs): | ||||||
|  |         # Disable reverse relation | ||||||
|  |         kwargs['related_name'] = '+' | ||||||
|  |         # Set unique to enable model cache. | ||||||
|  |         kwargs['unique'] = True | ||||||
|  |         super(CurrentTranslation, self).__init__(to, from_fields, to_fields, **kwargs) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class ArticleTranslation(models.Model): | ||||||
|  |  | ||||||
|  |     article = models.ForeignKey('indexes.Article') | ||||||
|  |     language = models.CharField(max_length=10, unique=True) | ||||||
|  |     content = models.TextField() | ||||||
|  |  | ||||||
|  |  | ||||||
| class Article(models.Model): | class Article(models.Model): | ||||||
|     headline = models.CharField(max_length=100) |     headline = models.CharField(max_length=100) | ||||||
|     pub_date = models.DateTimeField() |     pub_date = models.DateTimeField() | ||||||
|  |  | ||||||
|  |     # Add virtual relation to the ArticleTranslation model. | ||||||
|  |     translation = CurrentTranslation(ArticleTranslation, ['id'], ['article']) | ||||||
|  |  | ||||||
|     class Meta: |     class Meta: | ||||||
|         index_together = [ |         index_together = [ | ||||||
|             ["headline", "pub_date"], |             ["headline", "pub_date"], | ||||||
|   | |||||||
| @@ -29,3 +29,10 @@ class IndexesTests(TestCase): | |||||||
|         # unique=True and db_index=True should only create the varchar-specific |         # unique=True and db_index=True should only create the varchar-specific | ||||||
|         # index (#19441). |         # index (#19441). | ||||||
|         self.assertIn('("slug" varchar_pattern_ops)', index_sql[4]) |         self.assertIn('("slug" varchar_pattern_ops)', index_sql[4]) | ||||||
|  |  | ||||||
|  |     @skipUnless(connection.vendor == 'postgresql', | ||||||
|  |         "This is a postgresql-specific issue") | ||||||
|  |     def test_postgresql_virtual_relation_indexes(self): | ||||||
|  |         """Test indexes are not created for related objects""" | ||||||
|  |         index_sql = connection.creation.sql_indexes_for_model(Article, no_style()) | ||||||
|  |         self.assertEqual(len(index_sql), 1) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user