我有一个食谱模型。我有一个用于评论这些食谱的模型。食谱的作者(厨师)可以选择特定的评论作为他们的最爱。我想我已经正确设置了限制,每个食谱只允许一个最喜欢的评论。让我们假设每个食谱有一条最喜欢的评论。
我想参考一篇最喜欢的使用食谱模型的评论。这可能吗?下面的示例模板片段。
{% for recipe in recipes %}
<div>
<h2>{{ recipe.name }}</h2>
<p>{{ recipe.favoriteReview.content }} <small>by {{ recipe.favoriteReview.author }}</small></p>
<p>Email the chef: {{ recipe.chef.email }}</p>
</div>
{% endfor %}
这是模型的示例,但我觉得我从错误的方向接近这个模型并且碰壁了。
# Models as example
class User(AbstractUser):
pass
class Recipe(models.model):
name = models.CharField(max_length=64)
instructions = models.TextField(max_length=1000)
chef = models.ForeignKey("User", on_delete=models.SET_NULL, related_name="recipes")
#favoriteReview = The review with chefsFavorite=True and recipe matches this recipe
class Review(models.model):
author = models.ForeignKey("User", on_delete=models.SET_NULL, related_name="reviews")
rating = models.DecimalField(max_digits=2, decimal_places=2)
content = models.TextField(max_length=1000)
chefsFavorite = models.Boolean(default="True")
recipe = models.ForeignKey("Recipe", on_delete=models.CASCADE, related_name="recipes")
class Meta:
constraints = [
models.UniqueConstraint(fields=['recipe'], condition=models.Q(chefsFavorite=True), name="chefs_one_favorite_recipe_review"
]
您可以与额外字段建立m2m关系并在那里设置约束:
模型.py
class Recipe(models.Model):
...
class Review(models.Model):
...
favorites = models.ManyToManyField(User, through="ChefsFavoriteReview")
class ChefsFavoriteReview(models.Model):
user = models.ForeignKey(
User, on_delete=models.CASCADE, related_name="favorite_reviews"
)
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
review = models.ForeignKey(Review, on_delete=models.CASCADE)
class Meta:
constraints = [
UniqueConstraint(
fields=["user", "recipe"], name="chefs_one_favorite_recipe_review"
)
]
一个简单的例子:
views.py
def favorites(request):
favorites = (
get_user_model().objects.get(pk=request.user.pk)
.favorite_reviews.all()
)
return render(request, "favorites.html", {"favorites": favorites})
收藏夹.html
<body>
{{request.user.name}}
{% for obj in favorites %}
<div>
<h2>Recipe: {{obj.recipe.name}}</h2>
<hr />
<p>
{{obj.review.author}} says "{{obj.review.content}}" and gives this
recipe a rating of {{obj.review.rating}}
</p>
</div>
{% endfor %}
</body>