adder
adder

Reputation: 3698

ForeignKey to abstract model

I have an abstract Product model, and I wanted it to be able to hold more than one image, so I decided to make another Image model and have a ForeignKey to Product, however I quickly realised that's not possible. The reason I decided to go for abstract base model is performance gains since every child model is in its own table. Having a different Image model for each subclass sounds bad to me, since there will be more than 20 subclasses.

class Product(models.Model):
    title = models.CharField(max_length=50)
    description = models.CharField(max_length=50)
    category = models.ForeignKey('Category', on_delete=models.CASCADE, blank=False)

    class Meta:
        abstract = True

class Book(Product):
    author = models.CharField(max_length=50)
    publisher = models.CharField(max_length=50)

class Shoes(Product):
    colour = models.CharField(max_length=50)
    size = models.CharField(max_length=50)

class Image(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='images')
    image = models.ImageField(upload_to=get_image_path, blank=True, null=True)

How can I overcome the issue?

Upvotes: 1

Views: 61

Answers (1)

Lord Elrond
Lord Elrond

Reputation: 16072

You can use a ManyToManyField:

class Product(models.Model):
    title = models.CharField(max_length=50)
    description = models.CharField(max_length=50)
    category = models.ForeignKey('Category', on_delete=models.CASCADE, blank=False)
    images = models.ManyToManyField(Image)

    class Meta:
        abstract = True

inserting data:

b1 = Book.objects.create(...) #can't include M2M yet
i1 = Image.objects.create(...)
i2 = Image.objects.create(...)
b1.images.add(i1, i2)

You can query the images like this:

books = Book.objects.all().prefetch_related('images')
images_for_book_1 = books[0].images.all()

Upvotes: 1

Related Questions