### Attempt to construct objects in memory Source: https://github.com/wagtail/django-modelcluster/blob/main/README.rst Example of attempting to assign related objects to a model instance without database persistence. ```python beatles = Band(name='The Beatles') beatles.members = [ BandMember(name='John Lennon'), BandMember(name='Paul McCartney'), ] ``` -------------------------------- ### Instantiate and Process ClusterForm Source: https://context7.com/wagtail/django-modelcluster/llms.txt Demonstrates creating instances of a ClusterForm for both new and existing model instances, and processing submitted data. The form handles loading existing children and saving new or updated data, including related child objects. ```python # Create form for a new band form = BandForm() # Create form for existing band (loads existing children) beatles = Band.objects.get(name='The Beatles') form = BandForm(instance=beatles) # Process submitted data form = BandForm(request.POST, request.FILES, instance=beatles) if form.is_valid(): band = form.save(commit=False) # Creates in-memory cluster # Do additional processing... band.save() # Commits everything to database ``` -------------------------------- ### Implement ClusterableModel and ParentalKey Source: https://github.com/wagtail/django-modelcluster/blob/main/README.rst Using ClusterableModel and ParentalKey to manage related objects in memory until the parent is saved. ```python from modelcluster.models import ClusterableModel from modelcluster.fields import ParentalKey class Band(ClusterableModel): name = models.CharField(max_length=255) class BandMember(models.Model): band = ParentalKey('Band', related_name='members', on_delete=models.CASCADE) name = models.CharField(max_length=255) >>> beatles = Band(name='The Beatles') >>> beatles.members = [ ... BandMember(name='John Lennon'), ... BandMember(name='Paul McCartney'), ... ] >>> [member.name for member in beatles.members.all()] ['John Lennon', 'Paul McCartney'] >>> beatles.members.add(BandMember(name='George Harrison')) >>> beatles.members.count() 3 >>> beatles.save() # only now are the records written to the database ``` -------------------------------- ### Implement Multi-Table Inheritance Source: https://context7.com/wagtail/django-modelcluster/llms.txt Create hierarchies of ClusterableModel subclasses that support serialization and child relation management. ```python from modelcluster.models import ClusterableModel from modelcluster.fields import ParentalKey class Place(ClusterableModel): name = models.CharField(max_length=255) class Review(models.Model): place = ParentalKey('Place', related_name='reviews', on_delete=models.CASCADE) author = models.CharField(max_length=255) body = models.TextField() class Restaurant(Place): serves_hot_dogs = models.BooleanField(default=False) proprietor = models.ForeignKey('Chef', null=True, on_delete=models.SET_NULL) class SeafoodRestaurant(Restaurant): serves_oysters = models.BooleanField(default=True) # Create with inherited child relations fat_duck = Restaurant(name='The Fat Duck', serves_hot_dogs=False) fat_duck.reviews = [ Review(author='Michael Winner', body='Excellent!') ] # Serialize/deserialize preserves inheritance fat_duck_json = fat_duck.to_json() restored = Restaurant.from_json(fat_duck_json) print(restored.name) # The Fat Duck print(restored.serves_hot_dogs) # False print(restored.reviews.first().author) # Michael Winner # Second-level inheritance oyster_club = SeafoodRestaurant.from_json('{"pk": 43, "name": "The Oyster Club"}') print(oyster_club.place_ptr_id) # 43 print(oyster_club.restaurant_ptr_id) # 43 ``` -------------------------------- ### Manage Tags with ClusterTaggableManager Source: https://context7.com/wagtail/django-modelcluster/llms.txt Integrate django-taggit with ClusterableModel to handle tags in-memory before database persistence. ```python from taggit.models import TaggedItemBase from modelcluster.contrib.taggit import ClusterTaggableManager from modelcluster.fields import ParentalKey from modelcluster.models import ClusterableModel class TaggedPlace(TaggedItemBase): content_object = ParentalKey('Place', related_name='tagged_items', on_delete=models.CASCADE) class Place(ClusterableModel): name = models.CharField(max_length=255) tags = ClusterTaggableManager(through=TaggedPlace, blank=True) # Create place and add tags in memory restaurant = Place(name='The Fat Duck') restaurant.tags.add('fine-dining', 'british', 'michelin-starred') # Query tags before saving print(restaurant.tags.count()) # Output: 3 print(list(restaurant.tags.names())) # ['fine-dining', 'british', 'michelin-starred'] # Remove tags restaurant.tags.remove('british') print(restaurant.tags.count()) # Output: 2 # Clear all tags restaurant.tags.clear() # Set tags (replaces existing) restaurant.tags.set(['restaurant', 'uk']) # Save commits tags to database restaurant.save() ``` -------------------------------- ### Instantiate and Process Child Formset Source: https://context7.com/wagtail/django-modelcluster/llms.txt This snippet shows how to instantiate a child formset for a parent instance and process submitted data. The formset's save() method updates in-memory relations, and the parent's save() method commits all changes to the database. ```python # Use the formset with a parent instance beatles = Band(name='The Beatles') formset = BandMemberFormSet(instance=beatles) # Process formset data formset = BandMemberFormSet(request.POST, instance=beatles) if formset.is_valid(): formset.save(commit=False) # Updates in-memory relations beatles.save() # Commits to database ``` -------------------------------- ### Define ClusterableModel and ParentalKey Source: https://context7.com/wagtail/django-modelcluster/llms.txt Use ClusterableModel as a base for parent models and ParentalKey to define child relations that persist in memory until the parent is saved. ```python from django.db import models from modelcluster.models import ClusterableModel from modelcluster.fields import ParentalKey class Band(ClusterableModel): name = models.CharField(max_length=255) class BandMember(models.Model): band = ParentalKey('Band', related_name='members', on_delete=models.CASCADE) name = models.CharField(max_length=255) # Create a band with members without touching the database beatles = Band(name='The Beatles') beatles.members = [ BandMember(name='John Lennon'), BandMember(name='Paul McCartney'), ] # Query the in-memory objects using QuerySet-like API print(beatles.members.count()) # Output: 2 print(beatles.members.all()[0].name) # Output: John Lennon # Only now are the records written to the database beatles.save() ``` -------------------------------- ### Utilize FakeQuerySet for Full QuerySet API Support Source: https://context7.com/wagtail/django-modelcluster/llms.txt FakeQuerySet provides a comprehensive interface for in-memory collections, supporting advanced filtering, slicing, and aggregation methods. ```python from modelcluster.queryset import FakeQuerySet beatles = Band(name='The Beatles') beatles.members = [ BandMember(name='John Lennon'), BandMember(name='Paul McCartney'), BandMember(name='George Harrison'), BandMember(name='Ringo Starr'), ] # values_list() returns tuples names = beatles.members.values_list('name', flat=True) print(list(names)) # ['John Lennon', 'Paul McCartney', 'George Harrison', 'Ringo Starr'] # values() returns dictionaries member_dicts = beatles.members.values('name') print(list(member_dicts)) # [{'name': 'John Lennon'}, ...] # exclude() for negative filtering not_john = beatles.members.exclude(name='John Lennon') print(not_john.count()) # Output: 3 # Chained filtering result = beatles.members.filter(name__startswith='J').exclude(name__contains='Ringo') print(result.count()) # Output: 1 # distinct() for unique values print(beatles.members.distinct().count()) # Output: 4 # Slicing support print(beatles.members.all()[0:2]) # First two members # count() and exists() print(beatles.members.count()) # Output: 4 print(beatles.members.exists()) # Output: True ``` -------------------------------- ### ClusterForm and clusterform_factory Source: https://context7.com/wagtail/django-modelcluster/llms.txt Defines how to create forms for parent models that include child formsets, either by subclassing ClusterForm or using the clusterform_factory. ```APIDOC ## ClusterForm and clusterform_factory ### Description Defines how to create forms for parent models that include child formsets, either by subclassing ClusterForm or using the clusterform_factory. ### Method N/A (Class definition and factory function) ### Endpoint N/A ### Parameters N/A ### Request Example ```python # Define a ClusterForm with explicit formset inclusion class BandForm(ClusterForm): class Meta: model = Band fields = ['name'] formsets = ['members', 'albums'] # Include these child formsets # Or use the factory function BandForm = clusterform_factory( Band, fields=['name'], formsets=['members'], widgets={'name': forms.TextInput(attrs={'class': 'form-control'})} ) # Create form for a new band form = BandForm() # Create form for existing band (loads existing children) beatles = Band.objects.get(name='The Beatles') form = BandForm(instance=beatles) # Process submitted data form = BandForm(request.POST, request.FILES, instance=beatles) if form.is_valid(): band = form.save(commit=False) # Creates in-memory cluster # Do additional processing... band.save() # Commits everything to database # Access child formsets print(form.formsets['members']) # The members formset for member_form in form.formsets['members']: print(member_form.instance.name) ``` ### Response N/A ### Response Example N/A ``` -------------------------------- ### childformset_factory - Creating Child Formsets Source: https://context7.com/wagtail/django-modelcluster/llms.txt Creates formset classes for editing child objects that use ParentalKey, handling transient objects. ```APIDOC ## childformset_factory - Creating Child Formsets ### Description Creates formset classes for editing child objects that use ParentalKey, handling transient objects. ### Method N/A (Function definition) ### Endpoint N/A ### Parameters N/A ### Request Example ```python from modelcluster.forms import childformset_factory, ClusterForm # Create a formset for BandMember children of Band BandMemberFormSet = childformset_factory( Band, # parent model BandMember, # child model extra=3, # number of empty forms can_delete=True, can_order=True, # enable ordering if model has sort_order_field fields=['name'], min_num=1, validate_min=True, ) # Use the formset with a parent instance beatles = Band(name='The Beatles') formset = BandMemberFormSet(instance=beatles) # Process formset data formset = BandMemberFormSet(request.POST, instance=beatles) if formset.is_valid(): formset.save(commit=False) # Updates in-memory relations beatles.save() # Commits to database ``` ### Response N/A ### Response Example N/A ``` -------------------------------- ### Implement Nested Clusters with ParentalKey Source: https://context7.com/wagtail/django-modelcluster/llms.txt ParentalKey supports nested structures where child objects can themselves be ClusterableModel instances. ```python from django.db import models from modelcluster.models import ClusterableModel from modelcluster.fields import ParentalKey class Album(ClusterableModel): band = ParentalKey('Band', related_name='albums') name = models.CharField(max_length=255) release_date = models.DateField(null=True, blank=True) sort_order = models.IntegerField(null=True, blank=True) sort_order_field = 'sort_order' # Enable automatic ordering class Meta: ordering = ['sort_order'] class Song(models.Model): album = ParentalKey('Album', related_name='songs') name = models.CharField(max_length=255) # Create nested clusters beatles = Band(name='The Beatles') rubber_soul = Album(name='Rubber Soul', release_date=datetime.date(1965, 12, 3)) rubber_soul.songs = [ Song(name='Drive My Car'), Song(name='Norwegian Wood'), ] beatles.albums = [rubber_soul] # All nested objects are saved when the root parent is saved beatles.save() ``` -------------------------------- ### Create ClusterForm using clusterform_factory Source: https://context7.com/wagtail/django-modelcluster/llms.txt The clusterform_factory function provides a convenient way to create ClusterForm classes. It allows specifying the model, fields, formsets, and widgets directly. This is a more concise alternative to defining the form class manually. ```python BandForm = clusterform_factory( Band, fields=['name'], formsets=['members'], widgets={'name': forms.TextInput(attrs={'class': 'form-control'})} ) ``` -------------------------------- ### Define standard Django models Source: https://github.com/wagtail/django-modelcluster/blob/main/README.rst Standard Django models demonstrating the limitation of foreign key relations requiring database existence. ```python class Band(models.Model): name = models.CharField(max_length=255) class BandMember(models.Model): band = models.ForeignKey('Band', related_name='members', on_delete=models.CASCADE) name = models.CharField(max_length=255) ``` -------------------------------- ### Copy All Child Relations using copy_all_child_relations Source: https://context7.com/wagtail/django-modelcluster/llms.txt This function copies all ParentalKey child relations from one model instance to another. It supports excluding specific relations from the copy operation and can commit changes directly to the database. ```python # Create a band with multiple child relations original = Band(name='The Beatles') original.members = [BandMember(name='John Lennon')] original.albums = [Album(name='Abbey Road')] original.save() # Create target and copy all relations copy = Band(name='The Beatles Copy') copy.save() child_map = original.copy_all_child_relations( copy, exclude=['albums'], # Skip the albums relation commit=True ) print(copy.members.count()) # Output: 1 print(copy.albums.count()) # Output: 0 (excluded) ``` -------------------------------- ### copy_all_child_relations() - Copying All Children Source: https://context7.com/wagtail/django-modelcluster/llms.txt Copies all ParentalKey child relations from one model to another, with optional exclusions. ```APIDOC ## copy_all_child_relations() - Copying All Children ### Description Copies all ParentalKey child relations from one model to another, with optional exclusions. ### Method `copy_all_child_relations(target_instance, exclude=None, commit=False)` ### Endpoint N/A (Model method) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```python # Create a band with multiple child relations original = Band(name='The Beatles') original.members = [BandMember(name='John Lennon')] original.albums = [Album(name='Abbey Road')] original.save() # Create target and copy all relations copy = Band(name='The Beatles Copy') copy.save() child_map = original.copy_all_child_relations( copy, exclude=['albums'], # Skip the albums relation commit=True ) print(copy.members.count()) # Output: 1 print(copy.albums.count()) # Output: 0 (excluded) ``` ### Response N/A ### Response Example N/A ``` -------------------------------- ### Introspect child relations Source: https://github.com/wagtail/django-modelcluster/blob/main/README.rst Using get_all_child_relations to identify child relations on a parent model. ```python >>> from modelcluster.models import get_all_child_relations >>> get_all_child_relations(Band) [, ] ``` -------------------------------- ### Implement ParentalManyToManyField Source: https://github.com/wagtail/django-modelcluster/blob/main/README.rst Using ParentalManyToManyField for many-to-many relations that persist in memory until the parent is saved. ```python from modelcluster.models import ClusterableModel from modelcluster.fields import ParentalManyToManyField class Movie(ClusterableModel): title = models.CharField(max_length=255) actors = ParentalManyToManyField('Actor', related_name='movies') class Actor(models.Model): name = models.CharField(max_length=255) >>> harrison_ford = Actor.objects.create(name='Harrison Ford') >>> carrie_fisher = Actor.objects.create(name='Carrie Fisher') >>> star_wars = Movie(title='Star Wars') >>> star_wars.actors = [harrison_ford, carrie_fisher] >>> blade_runner = Movie(title='Blade Runner') >>> blade_runner.actors.add(harrison_ford) >>> star_wars.actors.count() 2 >>> [movie.title for movie in harrison_ford.movies.all()] # the Movie records are not in the database yet [] >>> star_wars.save() # Star Wars now exists in the database (along with the 'actor' relations) >>> [movie.title for movie in harrison_ford.movies.all()] ['Star Wars'] ``` -------------------------------- ### copy_cluster() - Deep Copy of Model and Children Source: https://context7.com/wagtail/django-modelcluster/llms.txt Creates a complete copy of a model instance including all child relations and ParentalManyToManyFields, returning an unsaved copy. ```APIDOC ## copy_cluster() - Deep Copy of Model and Children ### Description Creates a complete copy of a model instance including all child relations and ParentalManyToManyFields, returning an unsaved copy. ### Method `copy_cluster(exclude_fields=None, commit=False)` ### Endpoint N/A (Model method) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```python # Create original with nested relations original_band = Band(name='The Beatles') original_band.members = [ BandMember(name='John Lennon'), BandMember(name='Paul McCartney'), ] original_band.albums = [ Album(name='Abbey Road', songs=[ Song(name='Come Together'), Song(name='Something'), ]) ] original_band.save() # Create a deep copy (unsaved) copy, child_object_map = original_band.copy_cluster(exclude_fields=['id']) # Modify the copy copy.name = 'The Quarrymen' # The copy is independent of the original print(copy.members.count()) # Output: 2 print(copy.albums.first().songs.count()) # Output: 2 # Save the copy (creates new database records) copy.save() # Original is unchanged print(original_band.name) # The Beatles ``` ### Response N/A ### Response Example N/A ``` -------------------------------- ### Create Child Formset using childformset_factory Source: https://context7.com/wagtail/django-modelcluster/llms.txt The childformset_factory is used to create formset classes specifically for editing child objects related via ParentalKey. It handles transient objects and allows configuration of extra forms, deletion, ordering, and validation. ```python BandMemberFormSet = childformset_factory( Band, # parent model BandMember, # child model extra=3, # number of empty forms can_delete=True, can_order=True, # enable ordering if model has sort_order_field fields=['name'], min_num=1, validate_min=True, ) ``` -------------------------------- ### copy_child_relation() - Copying Child Objects Source: https://context7.com/wagtail/django-modelcluster/llms.txt Copies all objects from one child relation to another model instance, useful for duplicating content. ```APIDOC ## copy_child_relation() - Copying Child Objects ### Description Copies all objects from one child relation to another model instance, useful for duplicating content. ### Method `copy_child_relation(relation_name, target_instance, commit=False, append=False)` ### Endpoint N/A (Model method) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```python # Create source band with members source_band = Band(name='The Beatles') source_band.members = [ BandMember(name='John Lennon'), BandMember(name='Paul McCartney'), ] source_band.save() # Create target band target_band = Band(name='The Quarrymen') target_band.save() # Copy members from source to target child_object_map = source_band.copy_child_relation('members', target_band, commit=True) # The map contains (relation, old_pk) -> new_object mappings print(target_band.members.count()) # Output: 2 print(target_band.members.first().name) # John Lennon # Copy with append=True to add instead of replace another_band = Band.objects.create(name='Wings') another_band.members.add(BandMember(name='Linda McCartney')) another_band.save() source_band.copy_child_relation('members', another_band, commit=True, append=True) print(another_band.members.count()) # Output: 3 ``` ### Response N/A ### Response Example N/A ``` -------------------------------- ### Introspect Model Relations Source: https://context7.com/wagtail/django-modelcluster/llms.txt Retrieve ParentalKey and ParentalManyToManyField relations for dynamic processing of child objects. ```python from modelcluster.models import get_all_child_relations, get_all_child_m2m_relations # Get all ParentalKey child relations relations = get_all_child_relations(Band) for rel in relations: print(f"Relation: {rel.get_accessor_name()}") print(f"Related model: {rel.related_model}") # Output: # Relation: members # Related model: # Relation: albums # Related model: # Get all ParentalManyToManyField relations m2m_relations = get_all_child_m2m_relations(Article) for field in m2m_relations: print(f"M2M Field: {field.name}") # Output: # M2M Field: authors # M2M Field: categories ``` -------------------------------- ### Deep Copy Model and Children with copy_cluster Source: https://context7.com/wagtail/django-modelcluster/llms.txt The copy_cluster method performs a deep copy of a model instance, including all child relations and ParentalManyToManyFields. It returns an unsaved copy and a map of the copied child objects, allowing for independent modification before saving. ```python # Create original with nested relations original_band = Band(name='The Beatles') original_band.members = [ BandMember(name='John Lennon'), BandMember(name='Paul McCartney'), ] original_band.albums = [ Album(name='Abbey Road', songs=[ Song(name='Come Together'), Song(name='Something'), ]) ] original_band.save() # Create a deep copy (unsaved) copy, child_object_map = original_band.copy_cluster(exclude_fields=['id']) # Modify the copy copy.name = 'The Quarrymen' # The copy is independent of the original print(copy.members.count()) # Output: 2 print(copy.albums.first().songs.count()) # Output: 2 # Save the copy (creates new database records) copy.save() # Original is unchanged print(original_band.name) # The Beatles ``` -------------------------------- ### Copy Child Objects using copy_child_relation Source: https://context7.com/wagtail/django-modelcluster/llms.txt The copy_child_relation method duplicates all objects from a specified child relation to another model instance. It returns a map of copied objects and can optionally append to existing children instead of replacing them. ```python # Create source band with members source_band = Band(name='The Beatles') source_band.members = [ BandMember(name='John Lennon'), BandMember(name='Paul McCartney'), ] source_band.save() # Create target band target_band = Band(name='The Quarrymen') target_band.save() # Copy members from source to target child_object_map = source_band.copy_child_relation('members', target_band, commit=True) # The map contains (relation, old_pk) -> new_object mappings print(target_band.members.count()) # Output: 2 print(target_band.members.first().name) # John Lennon # Copy with append=True to add instead of replace another_band = Band.objects.create(name='Wings') another_band.members.add(BandMember(name='Linda McCartney')) another_band.save() source_band.copy_child_relation('members', another_band, commit=True, append=True) print(another_band.members.count()) # Output: 3 ``` -------------------------------- ### Serialize and Deserialize ClusterableModels Source: https://context7.com/wagtail/django-modelcluster/llms.txt ClusterableModel supports recursive JSON serialization and deserialization, including child relations and complex data types. ```python import datetime import json # Create a complex cluster with nested relations beatles = Band(name='The Beatles', members=[ BandMember(name='John Lennon'), BandMember(name='Paul McCartney'), ], albums=[ Album(name='Rubber Soul', release_date=datetime.date(1965, 12, 3)) ]) # Serialize to JSON beatles_json = beatles.to_json() print(beatles_json) # {"pk": null, "name": "The Beatles", "members": [{"pk": null, "name": "John Lennon", ...}, ...], "albums": [...]} # Get serializable dict (for custom processing) data = beatles.serializable_data() print(data['name']) # The Beatles print(len(data['members'])) # 2 # Deserialize from JSON restored_beatles = Band.from_json(beatles_json) print(restored_beatles.name) # The Beatles print(restored_beatles.members.count()) # 2 print(restored_beatles.albums.all()[0].release_date) # 1965-12-03 # Deserialize from dict beatles2 = Band.from_serializable_data({ 'pk': 9, 'name': 'The Beatles', 'albums': [], 'members': [ {'pk': None, 'name': 'John Lennon', 'band': None}, {'pk': None, 'name': 'Paul McCartney', 'band': None}, ] }) print(beatles2.id) # 9 print(beatles2.members.count()) # 2 ``` -------------------------------- ### Perform In-Memory QuerySet Operations with DeferringRelatedManager Source: https://context7.com/wagtail/django-modelcluster/llms.txt Use the related manager for ParentalKey fields to manipulate in-memory objects without database interaction until save or commit. Operations include filtering, adding, removing, and clearing related instances. ```python from modelcluster.fields import ParentalKey from modelcluster.models import ClusterableModel beatles = Band(name='The Beatles') # Use add() to append members beatles.members.add(BandMember(name='John Lennon')) beatles.members.add(BandMember(name='Paul McCartney')) beatles.members.add(BandMember(name='George Harrison')) # Filter with various lookups print(beatles.members.filter(name='Paul McCartney').count()) # Output: 1 print(beatles.members.filter(name__iexact='paul mccartNEY')[0].name) # Paul McCartney print(beatles.members.filter(name__contains='Cart').count()) # Output: 1 print(beatles.members.filter(name__startswith='John').count()) # Output: 1 print(beatles.members.filter(name__in=['John Lennon', 'Yoko Ono']).count()) # Output: 1 print(beatles.members.filter(name__lt='M').count()) # Output: 1 (George) print(beatles.members.filter(name__regex=r'n{2}').first().name) # John Lennon # get() for single objects member = beatles.members.get(name='Paul McCartney') # Existence and ordering print(beatles.members.filter(name='John Lennon').exists()) # Output: True print(beatles.members.first().name) # First member print(beatles.members.order_by('name').first().name) # George Harrison (alphabetical) print(beatles.members.order_by('-name').first().name) # Paul McCartney (reverse) # Remove specific members beatles.members.remove(beatles.members.get(name='George Harrison')) # Clear all members beatles.members.clear() ``` -------------------------------- ### Manage Many-to-Many Relations with ParentalManyToManyField Source: https://context7.com/wagtail/django-modelcluster/llms.txt ParentalManyToManyField manages many-to-many relationships in memory, but requires related objects to exist in the database first. ```python from django.db import models from modelcluster.models import ClusterableModel from modelcluster.fields import ParentalManyToManyField class Movie(ClusterableModel): title = models.CharField(max_length=255) actors = ParentalManyToManyField('Actor', related_name='movies') class Actor(models.Model): name = models.CharField(max_length=255) # Actors must be saved to the database first harrison_ford = Actor.objects.create(name='Harrison Ford') carrie_fisher = Actor.objects.create(name='Carrie Fisher') # Create movie and assign actors in memory star_wars = Movie(title='Star Wars') star_wars.actors = [harrison_ford, carrie_fisher] # Query works in memory before saving print(star_wars.actors.count()) # Output: 2 # The relation isn't in the database yet print([m.title for m in harrison_ford.movies.all()]) # Output: [] # Save commits the relations star_wars.save() print([m.title for m in harrison_ford.movies.all()]) # Output: ['Star Wars'] ``` -------------------------------- ### Introspect many-to-many child relations Source: https://github.com/wagtail/django-modelcluster/blob/main/README.rst Using get_all_child_m2m_relations to retrieve ParentalManyToManyField definitions. ```python >>> from modelcluster.models import get_all_child_m2m_relations >>> get_all_child_m2m_relations(Movie) ``` -------------------------------- ### Implement ClusterForm for Child Formsets Source: https://context7.com/wagtail/django-modelcluster/llms.txt ClusterForm extends Django's ModelForm to manage formsets for child relations defined with ParentalKey. ```python from django import forms from modelcluster.forms import ClusterForm, childformset_factory ``` -------------------------------- ### Define ClusterForm with Explicit Formset Inclusion Source: https://context7.com/wagtail/django-modelcluster/llms.txt Use ClusterForm to define a form for a model, explicitly including child formsets by name in the Meta class. This approach is useful when you need fine-grained control over which formsets are part of the main form. ```python class BandForm(ClusterForm): class Meta: model = Band fields = ['name'] formsets = ['members', 'albums'] # Include these child formsets ``` -------------------------------- ### Access Child Formsets within ClusterForm Source: https://context7.com/wagtail/django-modelcluster/llms.txt After a ClusterForm is processed, its child formsets are accessible via the 'formsets' attribute. This allows iterating through the forms in each child formset and accessing their instances. ```python # Access child formsets print(form.formsets['members']) # The members formset for member_form in form.formsets['members']: print(member_form.instance.name) ``` -------------------------------- ### Trigger database integrity error Source: https://github.com/wagtail/django-modelcluster/blob/main/README.rst The error encountered when attempting to save related objects without a parent ID. ```python IntegrityError: null value in column "band_id" violates not-null constraint ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.