mirror of
				https://github.com/django/django.git
				synced 2025-10-30 17:16:10 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			109 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from django.db import models
 | |
| from django.db.models.fields.related import ForwardManyToOneDescriptor
 | |
| from django.utils.translation import get_language
 | |
| 
 | |
| 
 | |
| class ArticleTranslationDescriptor(ForwardManyToOneDescriptor):
 | |
|     """
 | |
|     The set of articletranslation should not set any local fields.
 | |
|     """
 | |
|     def __set__(self, instance, value):
 | |
|         if instance is None:
 | |
|             raise AttributeError("%s must be accessed via instance" % self.field.name)
 | |
|         self.field.set_cached_value(instance, value)
 | |
|         if value is not None and not self.field.remote_field.multiple:
 | |
|             self.field.remote_field.set_cached_value(value, instance)
 | |
| 
 | |
| 
 | |
| class ColConstraint:
 | |
|     # Anything with as_sql() method works in get_extra_restriction().
 | |
|     def __init__(self, alias, col, value):
 | |
|         self.alias, self.col, self.value = alias, col, value
 | |
| 
 | |
|     def as_sql(self, compiler, connection):
 | |
|         qn = compiler.quote_name_unless_alias
 | |
|         return '%s.%s = %%s' % (qn(self.alias), qn(self.col)), [self.value]
 | |
| 
 | |
| 
 | |
| class ActiveTranslationField(models.ForeignObject):
 | |
|     """
 | |
|     This field will allow querying and fetching the currently active translation
 | |
|     for Article from ArticleTranslation.
 | |
|     """
 | |
|     requires_unique_target = False
 | |
| 
 | |
|     def get_extra_restriction(self, alias, related_alias):
 | |
|         return ColConstraint(alias, 'lang', get_language())
 | |
| 
 | |
|     def get_extra_descriptor_filter(self, instance):
 | |
|         return {'lang': get_language()}
 | |
| 
 | |
|     def contribute_to_class(self, cls, name):
 | |
|         super().contribute_to_class(cls, name)
 | |
|         setattr(cls, self.name, ArticleTranslationDescriptor(self))
 | |
| 
 | |
| 
 | |
| class ActiveTranslationFieldWithQ(ActiveTranslationField):
 | |
|     def get_extra_descriptor_filter(self, instance):
 | |
|         return models.Q(lang=get_language())
 | |
| 
 | |
| 
 | |
| class Article(models.Model):
 | |
|     active_translation = ActiveTranslationField(
 | |
|         'ArticleTranslation',
 | |
|         from_fields=['id'],
 | |
|         to_fields=['article'],
 | |
|         related_name='+',
 | |
|         on_delete=models.CASCADE,
 | |
|         null=True,
 | |
|     )
 | |
|     active_translation_q = ActiveTranslationFieldWithQ(
 | |
|         'ArticleTranslation',
 | |
|         from_fields=['id'],
 | |
|         to_fields=['article'],
 | |
|         related_name='+',
 | |
|         on_delete=models.CASCADE,
 | |
|         null=True,
 | |
|     )
 | |
|     pub_date = models.DateField()
 | |
| 
 | |
|     def __str__(self):
 | |
|         try:
 | |
|             return self.active_translation.title
 | |
|         except ArticleTranslation.DoesNotExist:
 | |
|             return '[No translation found]'
 | |
| 
 | |
| 
 | |
| class NewsArticle(Article):
 | |
|     pass
 | |
| 
 | |
| 
 | |
| class ArticleTranslation(models.Model):
 | |
|     article = models.ForeignKey(Article, models.CASCADE)
 | |
|     lang = models.CharField(max_length=2)
 | |
|     title = models.CharField(max_length=100)
 | |
|     body = models.TextField()
 | |
|     abstract = models.TextField(null=True)
 | |
| 
 | |
|     class Meta:
 | |
|         unique_together = ('article', 'lang')
 | |
| 
 | |
| 
 | |
| class ArticleTag(models.Model):
 | |
|     article = models.ForeignKey(
 | |
|         Article,
 | |
|         models.CASCADE,
 | |
|         related_name='tags',
 | |
|         related_query_name='tag',
 | |
|     )
 | |
|     name = models.CharField(max_length=255)
 | |
| 
 | |
| 
 | |
| class ArticleIdea(models.Model):
 | |
|     articles = models.ManyToManyField(
 | |
|         Article,
 | |
|         related_name='ideas',
 | |
|         related_query_name='idea_things',
 | |
|     )
 | |
|     name = models.CharField(max_length=255)
 |