Sunday, February 28, 2016

Re: Absolute beginner question -- recipes



On Sun, Feb 28, 2016 at 12:23 PM, Simon Gunacker <simon.gunacker@gmail.com> wrote:
Thank you Rahul,

I actually tried that an this is possible for the relationship between a recipe and its steps. But when it comes to the ingredients for a single step, I cannot do this any more since the ingredients depend on steps again. After reading your suggestion I thought about it once more and I came up with the following solution:

def detail(request, pk):
    recipe
= Recipe.objects.get(id=pk)

    steps
= Step.objects.filter(recipe_id=pk)

    ingredients
= dict()
   
for step in steps:
        ingredients
[step.id] = StepIngredients.objects.filter(step_id=step.id)

   
template = loader.get_template('recipe/rezept_detail.html')
    context
= {
       
'recipe': recipe,
       
'steps': steps,
       
'ingredients': ingredients
   
}
   
return HttpResponse(template.render(context, request))


Please review how the Django ORM works. You're creating much more work for yourself and your application. 50% of the code in this block can be removed.



def detail(request, pk):
    recipe 
= Recipe.objects.get(id=pk)

    template = loader.get_template('recipe/rezept_detail.html')
    context 
= {
        
'recipe': recipe,
    }
    
return HttpResponse(template.render(context, request))


I've already mentioned that separate calls to Step.objects are not necessary, because recipe.steps contains the results of such a query already.

The same applies to the ingredients for each step.

for step in recipe.steps:
    print('Ingredients: '.format(step.ingredients))
    # or
    for ingredient in step.ingredients:
        print(ingredient)

There is no need to have separate context variables within the template context for each piece of the recipe. All of the information that you are manually extracting is already available in the original object that was requested. The only exception that I would make is if you needed a separate list of all ingredients for all steps in one big list, which is much more difficult to extract. Even then, though, that sore of query is probably better handled by a model manager method that can be accessed via the template.

Of course, everything I'm saying is predicated on a decent model design. It could be that your current model structure doesn't allow for taking advantage of the ORM capabilities. If that's the case, though...you may want to review it.

 
However, when it comes to the view, it does not work any more:
<h1>{{ recipe.name }}</h1>

<table>
{% for step in steps %}

 
<tr>
   
<td>
    {% for ingredient in ingredients.step.id %}
      {{ ingredient.amount }}
    {% endfor %}
   
</td>

   
<td>{{ step.description }}</td>
 
</tr>

{% endfor %}
</table>

According to what I found on google, the django template language cannot deal with accessing dictionary entries using variables as keys. What is the django-way of solving this problem? Any ideas?

Yes, the template syntax is limited, intentionally. Assuming that you take my previous advice and utilize the recipe object directly:

<h1>{{ recipe.name }}</h1>

<table>
{% for step in recipe.steps %}

  
<tr>
    
<td>
    {% for ingredient in step.ingredients %}
      {{ ingredient.amount }}
    {% endfor %}
    
</td>

    
<td>{{ step.description }}</td>
  
</tr>

{% endfor %}
</table>

I have no idea why you are referring to ingredients.step.id in your template, it doesn't even make sense with the code you have (which is probably why things aren't behaving the way you'd expect). There really shouldn't be a need to ever refer to .id or .pk within a template, unless you are specifically printing out those values for an input field name or using {% url %}. 

Again, I'm making some assumptions about your models. If the above code snippets don't work (aside from typos), please post up your models.py file(s) so that we can adjust accordingly.

-James

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CA%2Be%2BciWPFUqwe9VXKTFWBJhQQUuNAEgtMFOjGxpxBtongM2SSg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment