= CookBook - Data Model = == Multiple Levels and Multiple Components == == Description == There are times when you have data/content that has many-to-one relationships. This is very easy to accomodate, just as [http://www.djangoproject.com/documentation/models/many_to_one/ this example] demonstrates. Here is code similar to that of the example: {{{ #!python from django.core import meta class Document(meta.Model): short_name = meta.CharField(maxlength=30) title = meta.CharField(maxlength=100) def __repr__(self): return self.title class META: admin = meta.Admin() class Paragraph(meta.Model): document = meta.ForeignKey( Document, edit_inline=True, num_in_admin=3, num_extra_on_change=1 ) content = meta.TextField() def __repr__(self): return self.headline }}} This is fantastic. It's convenient. ''But''... what if we have more than just two "levels"? What if our document data is divided into two types of data, say "summary" and "details"? And what if each of these views then has potentially multiple paragraphs? ''Stay tuned; more to come...'' == Code == == API Usage == == See Also == == A New Beginning == I haven't a clue where this was intended to go, but I've recently started working with something that has such multilevel 1:many relations. And I've seen questions about this even in the relatively little time I've spent on #django, so maybe even these sketchy notes will be useful. === Imagine a Perfectly Spherical Poll... === So a poll is one, with many related questions; likewise, each question has multiple related answers. One of my first cuts, inspired no doubt by having just learned about Django's template faciltiies, hence wanting to use them, looked something like this: {{{ #!python
    {% for q in poll.get_question_list %}
  1. {{ q.prompt }} {% for a in q.get_answer_list %}
    {{ a.response }} {% endfor %} {% if arg.show_blank %}
    {% endif %} {% endfor %}
}}} This requires really minimal setup in the view code - load the poll, set it up in the context dictionary that you'll pass to the rendering function, and there you go. The virtue of simplicity, but also the limitations, as I discovered. === It was about that time that the Vogons came along === Well, maybe it was a few minutes later. But I wanted to add some other features, such as an add-your-own-answer choice, but that needed to be conditional, and so forth. And I ran into the simple reality that the template language gets really ugly really fast if you need to do too much logic in it. Like, for example, adding the logic to set the radio button for a set of choices already made in the above display. Or if the ordering of the nested data isn't what you wanted. So I migrated some of the logic back into the view, and added a ''chosen_one'' attribute to the answers to make the template as simple as possible. I '''think''' this is a generally good approach, even though I didn't get any opinions one way or the other when I asked #django for such. So we'll see...