Personal Catalogue: Django & PostgreSQL — Chapter 2, Exercise 3 ==================================================== TASK Using the Django shell, create one book Item, create one Tag, attach the tag to the book via item.tags.add(tag), then confirm the relationship by printing item.tags.all(). SOLUTION Open the Django shell: python manage.py shell Then, inside the shell: >>> from catalogue.models import Item, ItemType, Tag >>> book_type = ItemType.objects.get(name='book') >>> item = Item.objects.create( ... item_type=book_type, ... title='FastAPI in Action', ... creator='Bill Lubanovic', ... release_year=2023, ... ) >>> tag = Tag.objects.create(name='Python') >>> item.tags.add(tag) >>> item.tags.all() ]> WHAT THIS ACTUALLY CONFIRMS item.tags.add(tag) writes a real row into the automatically-generated join table connecting this specific Item and this specific Tag - the same underlying mechanism as manually inserting a row into a hand-built item_tags table, just expressed through the ManyToManyField's own Python API instead of raw SQL. item.tags.all() then queries that join table (joined back to the Tag table) and returns every tag currently attached to this item, confirming the relationship was actually recorded rather than merely appearing to succeed. A useful follow-up check: querying from the other direction, tag.items.all() (using the related_name='items' set on the ManyToManyField), should return a QuerySet containing the same book Item - proving the relationship works symmetrically in both directions, exactly as a real many-to-many relationship should. WHY THIS WORKS AS AN ANSWER ---------------------------- It walks through the exact commands needed, explains what add() and all() are actually doing at the database level rather than treating them as opaque method calls, and suggests a real way to verify the relationship is genuinely bidirectional.