Home > Mobile >  django views many-to-many relationship field problem
django views many-to-many relationship field problem

Time:02-24

During work on my 1st app(kind of cookery book where it will be possible also to create meal plans) i have a problem to addapt one field from many-to-many(through) model to my html template. Field name is 'meal' in RecipeMealPlan model.

Here are my models:

class Recipe(models.Model):
    title = models.CharField(max_length=50)
    cooking_time = models.IntegerField(help_text='in minutes', validators=[MinValueValidator(1), MaxValueValidator(5000)])
    difficulty_level = models.IntegerField(choices=DIFFICULTY_LEVELS, default=1)
    description = models.TextField()
    created = models.DateTimeField(auto_now_add=True)
    cuisine = models.ForeignKey('Cuisine', on_delete=models.CASCADE, null=True)
    ingredient = models.ManyToManyField(Ingredient, through='IngredientRecipe')
    meal_plan = models.ManyToManyField('MealPlan', through='RecipeMealPlan')
    
class RecipeMealPlan(models.Model):
    recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
    meal_plan = models.ForeignKey('MealPlan', on_delete=models.CASCADE)
    meal = models.IntegerField(choices=MEALS)

    MEALS = (
        (1, 'Breakfast'),
        (2, '2nd breakfast'),
        (3, 'Lunch'),
        (4, 'Snack'),
        (5, 'Dinner')
    )

class MealPlan(models.Model):
    name = models.CharField(max_length=50)
    amount = models.IntegerField(validators=[MinValueValidator(4), MaxValueValidator(6)])

Here is my view created to show mealplan details on my app:

class MealPlanDetailsView(View):
    def get(self, request, id):
        mealplan = MealPlan.objects.get(id=id)
        recipes = mealplan.recipe_set.all()
        return render(request, 'diet_app/mealplan_details.html', {'mealplan': mealplan, 'recipes': recipes})

And html template:

    {% extends 'diet_app/base.html' %}
    {% block title %}{{ mealplan|upper }}{% endblock %}
    {% block content %}
                    <h2>{{ mealplan|upper }}</h2>
                    <ul> <p>Posiłki:</p>
                    {% for recipe in mealplan.recipemealplan_set.all %}
                        <li>{{ recipe.get_meal_display}}: <a href="/recipe/{{recipe.id}}/">{{ recipe }}</a></li>
                    {% endfor %}
                    </ul>
    {% endblock %}

Everything looks fine but link to receipe details doestnt work:

<a href="/recipe/{{recipe.id}}/">

Link works if i write the loop like this:

{% for recipe in recipes %}
<li><a href="/recipe/{{recipe.id}}/">{{ recipe.title }} </a></li>
{% endfor %}

But then i dont see meal name before recipe (meal name means Breakfast, dinner etc.). I don't how to write it down to see together meal name and recipe with link to recipe details.

I succeed only when i wrote those 2 loops combined but then i see my meal plan repeated few times.

Any ideas what should i do to make it work the way i want?

CodePudding user response:

recipe.id is the id of the through model RecipeMealPlan, and not Recipe, so instead of recipe.id, you need to use recipe.recipe.id.

Also for sanity's sake, you could use something like recipemealplan instead of recipe as the variable name, so:

    {% for recipemealplan in mealplan.recipemealplan_set.all %}
        <li>{{ recipemealplan.get_meal_display}}: <a href="/recipe/{{ recipemealplan.recipe.id }}/">{{ recipemealplan }}</a></li>
    {% endfor %}
  • Related