Search code examples
djangodjango-modelsforeign-keysone-to-manymany-to-one

Django Model Design many-to-one?


I'm trying to create two models in Django, 'Paragraph' and 'Sentences'. I still do not seem to understand how the many-to-one function works. If I want there to be a paragraph that holds multiple sentences; do I simply add a ForeignKey(Paragraph) into the Sentences model? That way I can have more than one sentence store inside the Paragraph model. Thank you for any insight as I try to learn Django.

    class Sentence(models.Model):
        text = models.TextField(blank=True)
        order_number = models.IntegerField()
    
        def __str__(self):
            return self.text
    
    class Paragraph(models.Model):
        text = models.TextField(blank=True)
        order_number = models.IntegerField()
        sentences = models.ForeignKey(Sentence, on_delete=models.CASCADE)
    
        def __str__(self):
            return self.text

Solution

  • A ForeignKey is a many-to-one relation. That means that multiple items where you define the model can link to the same item of the target model.

    Therefore Paragraph is thus the "parent" model, and Sentence the "child" model:

    class Paragraph(models.Model):
        text = models.TextField(blank=True)
        order_number = models.IntegerField()
    
        def __str__(self):
            return self.text
    
    class Sentence(models.Model):
        text = models.TextField(blank=True)
        order_number = models.IntegerField()
        paragraph = models.ForeignKey(
            Paragraph,
            on_delete=models.CASCADE,
            related_name='sentences'
        )
    
        def __str__(self):
            return self.text

    You thus can make a Paragraph and multiple sentences that all link to the same paragraph:

    p1 = Paragraph.objects.create(text='Act 3, Scene 1', order_number=0)
    s1 = Sentence.objects.create(
        text='To be, or not to be, that is the question',
        paragraph=p1,
        order_number=0
    )
    s2 = Sentence.objects.create(
        text='Whether 'tis nobler in the mind to suffer',
        paragraph=p1,
        order_number=1
    )

    You can then query all the related sentences of p1 with:

    p1.sentences.all()