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.