Могу ли я определить поле в модели 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>
Вернуться на верх