Jacob K
Jacob K

Reputation: 436

Django foreign key relation

I recently started working with Python and Django for making a website, and i've run into a problem that i just cannot figure out.

You can be sure, that it's becuase of my utter inexperience, and that i've overlooked something simple or done something dumb, but oh well..

On my site i have a page for displaying details about a recipe (description, ingredients, instructions and such). I'm displaying this like such:

views.py
class RecipeView(generic.DetailView):
    model = recipe
    template_name = 'whatsfordinner/recipe.html'
    context_object_name = 'details'

So far i've been able to display my single info things, no problem ( {{details.whatever}} )

My problem is that both instructions and ingredients are stored in my db as a foreign key relation, and as such needs to be outputted differently. My database looks like this:

class recipe(models.Model):
    title = models.CharField(max_length=255)
    description = models.TextField(default="No decsription added")
    image = models.ImageField(upload_to='images/',
                                        default='images/default.jpg')
    total_favourites = models.IntegerField()
    servings = models.IntegerField()

    def __str__(self):
        return self.title

class ingredients(models.Model):
    recipe = models.ForeignKey(recipe)
    ingredient = models.CharField(max_length=255)

I'm having a really hard time outputting the relevant ingredients for my selected recipe, and i would love some pointers.

Upvotes: 0

Views: 613

Answers (2)

Sushovan Mandal
Sushovan Mandal

Reputation: 1077

For an recipe object, say r:

r.ingredients_set.all() will list all the ingredients linked to that recipe.

You can further filter on this: r.ingredients_set.filter(title__startswith='clover')

There's a comprehensive guide in Django Documentation: https://docs.djangoproject.com/en/1.9/topics/db/examples/many_to_one/

Suppose you want the list of all ingredients for a recipe in your views.py:

ingredient_list = r.ingredients_set.all()

Then pass the ingredient_list in your context dictionary to your template. If you don't know what context dictionary is, what are you doing man, go through the Django documentation! Lot's of people put in lot of effort to create that nice documentation.

suppose context['ingredients'] = ingredient_list, where context is the context dictionary you are passing to your template html. Then in your template, use Django Template Language for something like this:

{% for i in ingredients %}
  <p>{{ i.ingredient }}</p>
{% endfor %}

Here ingredients is the ingredient_list you passed using the context dictionary, and for each ingredient object i in the for loop, you are displaying the value of <ingredient object i>.ingredient

Here's a link to the official tutorial, if it helps. https://docs.djangoproject.com/en/1.9/intro/tutorial01/

Upvotes: 1

joel goldstick
joel goldstick

Reputation: 4483

See here: https://docs.djangoproject.com/en/1.9/topics/class-based-views/generic-display/#adding-extra-context

class PublisherDetail(DetailView):

    model = Publisher


class RecipeView(generic.DetailView):
    model = recipe
    template_name = 'whatsfordinner/recipe.html'
    context_object_name = 'details'

    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super(RecipeView, self).get_context_data(**kwargs)
        # Add in a QuerySet of all the books
        context['ingredient_list'] = recipe.ingredients_set.all()
        return context

above is untested

Upvotes: 0

Related Questions