On Thursday, March 3, 2016 at 3:22:04 AM UTC+11, Simon Gunacker wrote:
>
> Inspired by Mike Dewhirsts suggestion on building hierachical structures, 
>


Not sure we are on the same page regarding "hierarchical". In the early 
days hierarchical databases only had 1:n relationships IOW foreign keys 
only. That is a very limiting thing. You have to turn your thinking inside 
out to successfully represent the real world.  That's what I meant. OTOH, 
RDBMS gives you everything you need to represent the real world. 

 

> I've made up another model:
> class Part(models.Model):
>     parts = models.ForeignKey('Part', null=True, blank=True, default=None, 
> related_name='pieces')
>     name = models.CharField(max_length=200)
>
>
For this to work in Django the table name should probably be 'self' rather 
than 'Part'. Haven't checked the docs on this recently.

Your 'parts' FK lets any Part be connected to exactly one or (null=True) no 
other part. Is that what your real world is? If so, why did you use plural 
nouns as the fieldname and related_name identifiers? Choosing meaningful 
names is very helpful when you revisit your code in future. 

If your real world scenario is the "bill of materials" I mentioned earlier, 
you really need a many-to-many relationship between parts. That means any 
part could be in a number of different parts (ie assemblies) and assemblies 
themselves could actually be sub-assemblies in a finished product - which 
amounts to an assembly of sub-assemblies. If so, we might be getting close 
to your original recipes project.

Consider that what we need behind the scenes to represent a many-to-many 
relationship is a bunch of records in a "through" table (let's call it 
"Parts" plural) and all it needs is two FKs. Lets say fk1 points to the 
precise row in the Part table which happens to be an assembly or 
sub-assembly. fk1 in the through table would never point to a stand-alone 
part. Then fk2 would point to another row in the Part table. That other row 
is a part as well. It could represent a sub-assembly or a stand-alone part 
but never a complete assembly. 

So when you want to know what all the parts are for an assembly you need a 
view which understands your business logic and can run the appropriate 
query to retrieve the results you want into a queryset, list or whatever. 
Assuming the result you want is a list of an assembly's parts, you would 
first identify the assembly in the Part table then query the "through" 
table (Parts) for all the rows with fk1==Part
 
 

> Then I made my view:
> class PartsView(generic.ListView):
>     context_object_name='parts'
>     model=Part
>
>
I have never tried generic views.

My typical approach is to create an arbitrary object (eg class 
Assembly(object)) and use its __init__() method to instantiate an assembly 
object with the queryset, list or whatever generated by the code in the 
view. In the hypothetical example I'm conjuring up here we would pass in 
Part.name as assembly.name and the queryset as assembly.qs (or similar 
identifiers).

 

> But how should I design my template now?
> <h1>Parts</h1>
>
> <ul>
> {% for part in parts %}
>   <li></li>
> {% endfor %}
> </ul>
>
>
<h1>Parts</h1>
<p>{{ assembly.name }}</p>
{% if assembly.qs %}
<ul>
{% for item in assembly.qs %}
<li>{{ item.fk2.name }}</li>
{% endfor %}
</ul>
{% else %}
<p>No parts</p>
{% endif %}

(each item represents a row in the through table Parts with fk2 being the 
sub-assembly or part)
 

That is all fine and dandy but what if you wanted more information about 
the particular spot the part needed to be placed or the way it should be 
aligned in the assembly? That information doesn't belong in the Parts table 
for the part concerned because it might be in many assemblies. Likewise it 
doesn't belong in the Parts table for the assembly concerned because there 
could be heaps and heaps of parts involved. It actually belongs in the 
"through" table Parts (plural). A single row in that table uniquely defines 
the relationship between assembly and part. If we add extra fields in the 
Parts "through" table those fields can carry whatever extra info is 
required. 

Note that the queryset performed in the view retrieved records from the 
Parts table. That means if each row contains extra info you can simply show 
it in your template as follows ...

{% for item in assembly.qs %}
<li>{{ item.fk2.name }} Alignment {{ item.fk2.alignment }}</li>
{% endfor %}

Hope this helps

Mike
 


I already found different answers on the net reaching from 'impossible' to 
> 'with-tag' or 'install some add-ons'. According to Mikes former suggestion, 
> I expected something easy and elegant here ...
>
> regards, Simon
>
>
>

-- 
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+unsubscr...@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/291d1c2a-627c-4765-8109-df02e84abdac%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to