Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>All <code>select_related</code> does, is eagerly fetch the fields declared as <code>ForeignKey</code> within your model. It attempts to avoid extra database calls, it doesn't magically give you access to extra fields.</p> <p>In your example, that means that accessing <code>partassembly.subpart</code> will not result in an extra database select, since it was eagerly fetched with the <code>PartAssembly.objects.filter()</code> call.</p> <p>Your data model seems to be incorrect, but we'll get to that in a minute. First, I'll show you how to access all the bits and pieces with your current data model.</p> <pre><code>{% for partassembly in subpart_list %} &lt;tr&gt; &lt;td&gt;{{ partassembly.item_no }}&lt;/td&gt; {% for subpart in partassembly.subpart.subpart_set %} # database hit &lt;td&gt;{{ subpart.subpart }}&lt;/td&gt; &lt;td&gt;{{ subpart.subpart.description }}&lt;/td&gt; # database hit &lt;td&gt;{{ subpart.subpart.rev }}&lt;/td&gt; &lt;td&gt;{{ subpart.qty }}&lt;/td&gt; &lt;td&gt;{{ subpart.subpart.isc }}&lt;/td&gt; {% endfor %} &lt;/tr&gt; </code></pre> <p>Unfortunately, you have no way of knowing how far you need to recurse. You can access the part within the original PartAssembly, and you can reach the set of PartAssemblys from that Part, but there is no easy way of reaching the PartAssembly set for all Parts within the first PartAssembly. Wow, that was a mouthful!</p> <p>Now, onto your data model.</p> <p>Say you have a Part called a "3mm screw". That sounds like it could be used for a number of different Assemblys (I'm intentionally not using the 'ies' plural form). So you have an Assembly called a Desk, and an Assembly called a Chair. Each uses many of these 3mm screws. You want to describe how to build a Desk.</p> <pre><code> desk = PartAssembly.objects.filter(id=assemblyid) part = desk.subpart # lets pretend this returns a 3mm screw subassemblies = part.subpart_set.all() for a in subassemblies: a.subpart.description # could be a Chair, or a Desk, or anything really! </code></pre> <p>This happens because a single instance of a 3mm Screw (or ANY part), is shared between all assemblies. You aren't truly replicating a ManyToMany table at all. Your datamodel is saying that a single Part can be used in many Assemblys.</p> <p>What I think you really want to say, is that an Assembly can be a part of another Assembly. Each Assembly as a number of Parts associated with its construction.</p> <pre><code>class Assembly(models.Model): parent = models.ForeignKey('self', null=True, blank=True, related_name='children') parts = models.ManyToManyField(Part) name = models.CharField(max_length=..) </code></pre> <p>Now, when you want to build a chair, you can do something like:</p> <pre><code>assembly = Assembly.objects.get(name='Chair') children = assembly.children.all() print assembly for part in assembly.parts: print part # now you iterate over the tree of children, printing their parts as you go </code></pre> <p>So, your Assembly model has now transformed into a Tree structure of other Assemblys, each containing their own set of Parts. Now that you can recognise this is a Tree structure, you can investigate how to represent this structure in a database within Django.</p> <p>Luckily, there exists a library that does exactly this. <a href="https://github.com/django-mptt/django-mptt/" rel="nofollow">django-mptt</a> exists to help you represent tree structures. It gives you methods for iterating over the entire tree, and describing each tree in your templates.</p> <p>I know I've probably helped cause you more work than you thought would be required, but I think this will truly help you.</p> <p>Best of luck.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload