Django two table relationship, but not both

送分小仙女□ 提交于 2020-01-24 20:32:08

问题


I have a table called Post. A post can have 2 videos or 2 images, but not both. The table schema for a post looks like this:

class Post(models.Model):
    user            = models.ForeignKey(User, on_delete=models.CASCADE)
    header          = models.CharField()
    created_at      = models.DateTimeField(auto_now_add=True)

I have two tables that look similar to each other:

class PostImage(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    img  = models.ImageField()


class PostVideo(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    video = models.FileField()

How do I create and enforce the relationship where a post can have maximum and minimum of 2 images or 2 videos, but it can't have both videos and images at the same time? Or is there a better way to do this?


回答1:


Probably you can write a Mixin class like this:

class PostMixin(object):
    def save(self, *args, **kwargs):
        if hasattr(self, 'img') and self.post.images.exists():
             raise ValidationError('Already have an image')
        elif hasattr(self, 'video') and self.post.videos.exists():
             raise ValidationError('Already have a video')
        super(PostMixin, self).save(*args, **kwargs)

class PostImage(PostMixin, models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="images")
    img  = models.ImageField()


class PostVideo(PostMixin, models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="videos")
    video = models.FileField()

But rather than handling them in model, you should handle them in forms or serializers(if you are using DRF).




回答2:


Another method is to add a pre_save signal for both PostImage and PostVideo and check your conditions there:

@receiver(pre_save, sender=PostVideo)
@receiver(pre_save, sender=PostImage)
def post_validator(sender, instance, *args, **kwargs):
    images_count = instance.post.postimage_set.count()
    videos_count = instance.post.postvideo_set.count()
    if not (<your conditions met>):
        raise ValidationError('Conditions not met!')


来源:https://stackoverflow.com/questions/59403910/django-two-table-relationship-but-not-both

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!