djangodjango-modelswagtailwagtail-snippet

Assigning a foreign key creates a new object


I'm trying to create a One-To-Many relationship in django which is working fine so far.

@register_snippet
class CarPart(models.Model):
    title = models.CharField(max_length=50)

    class Meta:
        verbose_name_plural = 'Car Parts'

    def __str__(self):
        return self.title

class CarParts(CarPart):
    source_page = ParentalKey(
        'home.CarPage', related_name='carparts'
    )

    carpart = models.ForeignKey(
        CarPart,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )

    panels = [
        SnippetChooserPanel('catpart'),
    ]

class CarPage(BasePage):
    content_panels = BasePage.content_panels + [
       InlinePanel('carparts', label="Car Part"),
    ]
    def get_context(self, request):
       context = super().get_context(request)

    return context

This is working fine - I can assign multiple car parts to a car but the problem is whenever I assign a car part it automatically creates a new empty objects other than the original data in Car Parts snippet or table.

It's showing correct parts when I do

{% for part in car.carparts.all %} 
    {{ part.title }}
{% endfor %}

But when I delete the empty objects from car parts snippet, it deletes the car parts in car and the for loop doesn't seem to show any value as the related car parts are deleted. I don't understand why it is creating new empty objects but assigning the correct ids.

Like:

If I select car part engine from page editor and save it - it creates a new empty object but the id seems to be correct. It shows engine in page layout but when I delete the new empty object, the related engine association is gone.


Solution

  • CartParts shouldn't inherit from CarPart and also have a foreign key to it.

    class CarParts(models.Model):
        source_page = ParentalKey(
            'home.CarPage', related_name='carparts'
        )
    
        carpart = models.ForeignKey(
            CarPart,
            null=True,
            blank=True,
            on_delete=models.SET_NULL,
            related_name='+'
        )
    
        panels = [
            SnippetChooserPanel('catpart'),
        ]