Могу ли я определить поле в модели django для возврата данных из другой модели, удовлетворяющих определенным условиям?
У меня есть модель для рецептов. У меня есть модель для отзывов на эти рецепты. Автор рецепта (шеф-повар) может выбрать конкретный отзыв как любимый. Я думаю, что правильно настроил ограничение, чтобы разрешить только один любимый отзыв на рецепт. Предположим, что на один рецепт приходится один любимый отзыв.
Я хотел бы ссылаться на один любимый обзор, используя модель рецептов. Возможно ли это? Пример шаблонного сниппета ниже.
{% 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-отношение с дополнительными полями и установить в нем ограничения:
models.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})
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>