在Django中创建条件Many to Many关系

huangapple go评论162阅读模式
英文:

Creating a conditional Many to Many relation in Django

问题

看起来很容易,但我仍然不知道如何实现它。

尝试在三个模型之间创建多对多的条件关系(不确定是否是正确的命名方式!):

  1. Class Book(models.Model):
  2. book_name = models.CharField(max_length=50)
  3. Class Article(models.Model):
  4. article_name = models.CharField(max_length=50)
  5. Class Portfolio(models.Model):
  6. KINDS = [('B', 'Book'), ('A', 'Article')]
  7. book = models.ForeignKey(Book, on_delete=models.PROTECT)
  8. article = models.ForeignKey(Article, on_delete=models.PROTECT)
  9. kind = models.models.CharField(max_length=1, choices=KINDS)
  10. user = models.ManyToManyField(User, through='Recommendation')
  11. Class Recommendation(models.Model):
  12. user = models.ForeignKey(User, on_delete=models.PROTECT)
  13. portfolio = models.ForeignKey(Book, on_delete=models.PROTECT)
  14. date = models.DateTimeField()
英文:

It seems easy but I still can't figure out how to implement it.

Trying to create a Many to Many conditional relations (not sure if it's the correct way to name it!) between three models:

  1. Class Book(models.Model):
  2. book_name = models.CharField(max_length=50)
  3. Class Article(models.Model):
  4. article_name = models.CharField(max_length=50)
  5. Class Portfolio(models.Model):
  6. KINDS = [('B', 'Book'), ('A', 'Article')]
  7. book = models.ForeignKey(Book, on_delete=models.PROTECT)
  8. article = models.ForeignKey(Article, on_delete=models.PROTECT)
  9. kind = models.models.CharField(max_length=1, choices=KINDS)
  10. user = models.ManyToManyField(User, through='Recommendation')
  11. Class Recommendation(models.Model):
  12. user = models.ForeignKey(User, on_delete=models.PROTECT)
  13. portfolio = models.ForeignKey(Book, on_delete=models.PROTECT)
  14. date = models.DateTimeField()

Each User (from the Django User module) can have multiple recommendations of portfolios. Each Portfolio is a group of books and articles recommended on a specific date.

答案1

得分: 2

我会跳过 Portfolio Model,直接这样实现:

  1. class Book(models.Model):
  2. book_name = models.CharField(max_length=50)
  3. class Article(models.Model):
  4. article_name = models.CharField(max_length=50)
  5. class Recommendation(models.Model):
  6. user = models.ForeignKey(User, on_delete=models.PROTECT)
  7. book = models.ForeignKey(
  8. Book,
  9. blank=True,
  10. null=True,
  11. on_delete=models.PROTECT
  12. )
  13. article = models.ForeignKey(
  14. Article,
  15. blank=True,
  16. null=True,
  17. on_delete=models.PROTECT
  18. )
  19. date = models.DateTimeField()
  20. class Meta:
  21. constraints = [
  22. models.CheckConstraint(
  23. check=Q(book__isnull=True, article__isnull=False) | Q(book__isnull=False, article__isnull=True),
  24. name='only_book_or_article'
  25. )
  26. ]

你可以跳过约束,但这样可能会导致你的数据不一致。

英文:

I would skip the Portfolio Model and just implement it this way:

  1. class Book(models.Model):
  2. book_name = models.CharField(max_length=50)
  3. class Article(models.Model):
  4. article_name = models.CharField(max_length=50)
  5. class Recommendation(models.Model):
  6. user = models.ForeignKey(User, on_delete=models.PROTECT)
  7. book = models.ForeignKey(
  8. Book,
  9. blank=True,
  10. null=True,
  11. on_delete=models.PROTECT
  12. )
  13. article = models.ForeignKey(
  14. Article,
  15. blank=True,
  16. null=True,
  17. on_delete=models.PROTECT
  18. )
  19. date = models.DateTimeField()
  20. class Meta:
  21. constraints = [
  22. models.CheckConstraint(
  23. check=Q(book__isnull=True, article__isnull=False) | Q(book__isnull=False, article__isnull=True),
  24. name='only_book_or_article'
  25. )
  26. ]

you could skip the constrains but than you risk that your data is inconsistent

huangapple
  • 本文由 发表于 2020年1月7日 02:08:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/59616890.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定