On 7/03/2016 2:17 AM, Mike Dewhirst wrote:
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:
    |
    classPart(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.

On rereading this, I should have said that for all the records (rows) in the "bunch" the fk1 always points to the same primary key in the Part table while every fk2 points to a different PK in the Part table.

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.

And further, I neglected to mention that Django manages all this for you when you put ...

class Part(models.Model):
    parts = ManyToManyField(null=True, blank=True, related_name=pieces")

... and working with this requires a few round-trips to the docs.

Mike


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:
    |
    classPartsView(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
<mailto:django-users+unsubscr...@googlegroups.com>.
To post to this group, send email to django-users@googlegroups.com
<mailto: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
<https://groups.google.com/d/msgid/django-users/291d1c2a-627c-4765-8109-df02e84abdac%40googlegroups.com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout.

--
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/56DCAF0B.5040502%40dewhirst.com.au.
For more options, visit https://groups.google.com/d/optout.

Reply via email to