Home > Net >  Django - Linking Models
Django - Linking Models

Time:01-03

I am using django and I want to link two models. The first model is comment and the second model is image. I want to have multiple images for one comment and an image should be linked with only one comment.

Comment model has its fields and image model looks like this:

class Image(models.Model):
    image = models.ImageField(upload_to=f'{hash(id)}/', null=True, blank=True)

    def __str__(self):
        return self.image.name

And this is the model that I used to link comment and image:

class CommentImage(models.Model):
    comment = models.OneToOneField(Comment, models.CASCADE, null=True)
    image = models.ForeignKey(Image, models.CASCADE, null=True)

    class Meta:
        ordering = ["-id"]
        verbose_name = _("Image")
        verbose_name_plural = _("Images")

    def __str__(self):
        return self.image.image.name

Here is the admin panel of django:

enter image description here

As you can see I could be able add only one image and there is no button as well to add multiple image. What should I change to be able to add multiple images?

I have tried using ManytoManyField and removing comment field from CommentImage but it did not work.

CodePudding user response:

I think you are overcomplicating things. Why not just add a text field to your ImageComment:

class Image(models.Model):
    def upload_to(self, filename):
        return f'{hash(self)}/{filename}'

    image = models.ImageField(upload_to=upload_to, null=True, blank=True)
    comment = models.ForeignKey(
        'ImageComment', on_delete=models.SET_NULL, null=True
    )

    def __str__(self):
        return self.image.name


class CommentImage(models.Model):
    comment = models.TextField()

Or in case an Image can have multiple ImageComments as well, use a ManyToManyField:

class Image(models.Model):
    def upload_to(self, filename):
        return f'{hash(self)}/{filename}'

    image = models.ImageField(upload_to=upload_to, null=True, blank=True)
    comments = models.ManyToManyField(
        'ImageComment'
    )

    def __str__(self):
        return self.image.name


class CommentImage(models.Model):
    comment = models.TextField()

You can even add an InlineModelAdmin to make editing comments at the same location as the image possible:

from django.contrib import admin


class ImageCommentInline(admin.TabularInline):
    model = ImageComment


@admin.site.register(Image)
class ImageAdmin(admin.ModelAdmin):
    inlines = [
        ImageCommentInline,
    ]

CodePudding user response:

You can try using this via manytomanyfields:

class CommentImage(models.Model):
    comment = models.ForeignKey(Comment, models.CASCADE)
    image = models.ForeignKey(Image, models.CASCADE)

class Comment(models.Model):
    # other fields here
    images = models.ManyToManyField(Image, through='CommentImage', related_name='comments')
  • Related