Architecture¶
Core Design: Grouper + Content Pattern¶
djangocms-custom-content uses a two-model pattern:
- Grouper - One per item (e.g., Article)
Persistent identity
Minimal data
Links to many Content objects
- Content - One per language (e.g., ArticleContent)
Language-specific data (title, body)
Version history automatically supported
Quick language switching
Why This Design?
Multilingual by default - Add language by creating new Content object
Version history - Old Content objects remain in database
Clean separation - Grouper is identity, Content is presentation
Efficient - One query per language
Example:
# One Article (grouper)
article = Article.objects.create(name="My Article")
# Multiple ArticleContent (per language)
content_en = ArticleContent.objects.create(
article=article,
language="en",
title="English Title",
body="English content..."
)
content_de = ArticleContent.objects.create(
article=article,
language="de",
title="German Title",
body="German content..."
)
M2M Relations Use Generic FK¶
Generic foreign keys allow flexible relationships:
class PersonRelation(AbstractCustomRelation):
instance = ForeignKey(PersonContent) # Which person
content_type = ForeignKey(ContentType) # What model type
object_id = PositiveIntegerField() # Which object
related_field_name = CharField() # "authors", "contributors", etc.
This single model stores relationships to ANY Django model without FK hardcoding.
See Also¶
M2M Relationships Explained - How M2M works internally