On 21/12/2016 9:10 PM, C. Kirby wrote:
> Mike, I've done a lot of work with Model meta, and I'm pretty sure I
> can give you at least the bones of a solution, but I can't really get
> my head around the problem. Could you post a set of related models and
> what you would expect the result to look like?
I have a main model (substance) with a bunch of child models
(properties, toxicity, health, spill etc) containing TextFields with
advice for that substance. There are obviously lots of substances and
they carry varying advice in their child models. Two of them are MMA
and Styrene.
With a new substance (eg Base Resin CK90) which is a mixture of those
two substances, the chemical manufacturer needs to assemble advice in
those same TextFields in the CK90 mixture as the ones in the child
models carrying the varying advice. In some cases that advice (eg spill
advice) can come out of an expert's head and just be typed in. In some
cases the expert may prefer to see the spill advice from all the
ingredient substances first. Like so ... [1]
... editing out the ingredient names - in this case MMA and Styrene -
and combining the advice for the mixture, getting rid of redundant or
repetitive advice.
The concat_fields method which sources the advice only works for a
mixture (ie substance has ingredients). It only works on a blank field
or (when signalled) replaces advice from one or more ingredients. The
user deletes one (or more) of the ingredient names and inserts an
ellipsis in the CK90 field. The advice from that/those ingredient(s)
will be appended. If another ingredient is added to the mixture and an
ellipsis is inserted in the CK90 mixture TextField, the new ingredient
advice is appended.
The models are pretty standard ... there are more than the 1:1 (Spill)
and 1:n (Exposure) shown here.
Substance (main model)
ingredients = models.ManyToManyField('self', symmetrical=False,
blank=True,
through='Substance_Ingredients',)
Substance_Ingredients (m2m 'through' table)
substance = models.ForeignKey('Substance')
ingredient = models.ForeignKey('Substance')
proportion = models.DecimalField()
Spill (1:1 model)
substance = models.OneToOneField('Substance')
small = models.TextField(verbose_name="Small spill",
help_text="Response recommended for spills around 25 litres.")
Exposure (1:n model)
substance = models.ForeignKey('Substance', related_name='route')
symptoms = models.TextField(help_text="Potential adverse health
effects and symptoms from "
"the first at lowest exposure through to consequences of severe
exposure.")
Thanks CK
Mike
[1] For those not seeing the embedded image, it is a TextField
containing the following words:
Methyl methacrylate monomer: Soak up with inert absorbent material (e.g.
silica gel, acid binder, universal binder, sawdust). Keep in suitable,
closed containers for disposal.
Styrene: Soak up with inert absorbent material (e.g. sawdust). Keep in
closed containers for disposal.
>
> On Wednesday, December 21, 2016 at 4:55:49 AM UTC+2, Mike Dewhirst wrote:
>
> Bumping this question again, I have done all the individual
> concatenations with the following model method ...
>
> def concat_fields(self, ingredients):
> """ ingredients is a queryset of substance:substance m2m records
> with the second FK to substance in a field called "ingredient"
> Objective is concatenate text from all text fields into the
> mixture
> """
> if ingredients:
> objects = list()
> ellip = "..."
> for m2m in ingredients:
> obj = m2m.ingredient.get_health()
> if obj:
> objects.append(obj)
> if objects:
> # first of seven text fields in this model
> comment = self.ototoxic_comment or ""
> comment = comment.strip()
> if comment:
> comment = "{0}\n".format(comment.strip())
> if not comment or ellip in comment:
> for obj in objects:
> if not
obj.substance.name
> <
http://obj.substance.name> in comment:
> if obj.ototoxic_comment:
> comment = "{0}{1}:
> {2}\n".format(comment,
>
obj.substance.name <
http://obj.substance.name>, obj.ototoxic_comment)
> <
http://obj.substance.name>
> > text = obj.stability_comment
> > comment = "{0}\n{1}: {2}".format(comment, name,
> text)
> > comment = comment.strip()
> > if comment:
> > self.stability_comment = comment
> >
> > if not self.reactivity:
> > comment = ""
> > for obj in state_objs:
> > if obj.reactivity:
> > name =
obj.substance.name
> <
http://obj.substance.name>
> > text = obj.reactivity
> > comment = "{0}\n{1}: {2}".format(comment, name,
> text)
> > comment = comment.strip()
> > if comment:
> > self.reactivity = comment
> >
> > if not self.reaction_hazards:
> > comment = ""
> > for obj in state_objs:
> > if obj.reaction_hazards:
> > name =
obj.substance.name
> <
http://obj.substance.name>
> > text = obj.reaction_hazards
> > comment = "{0}\n{1}: {2}".format(comment, name,
> text)
> > comment = comment.strip()
> > if comment:
> > self.reaction_hazards = comment
> >
> > if not self.avoid:
> > comment = ""
> > for obj in state_objs:
> > if obj.avoid:
> > name =
obj.substance.name
> <
http://obj.substance.name>
> > text = obj.avoid
> > comment = "{0}\n{1}: {2}".format(comment, name,
> text)
> > comment = comment.strip()
> > if comment:
> > self.avoid = comment
> >
> > if not self.incompatibilities:
> > comment = ""
> > for obj in state_objs:
> > if obj.incompatibilities:
> > name =
obj.substance.name
> <
http://obj.substance.name>
> > text = obj.incompatibilities
> > comment = "{0}\n{1}: {2}".format(comment, name,
> text)
> > comment = comment.strip()
> > if comment:
> > self.incompatibilities = comment
> >
> > Thanks
> >
> > Mike
> >
> >
>
> --
> 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...@googlegroups.com
> <mailto:
django-users...@googlegroups.com>.
> <mailto:
django...@googlegroups.com>.
>
https://groups.google.com/d/msgid/django-users/54e68516-af14-41f4-a47b-0088a6ce023d%40googlegroups.com
> <
https://groups.google.com/d/msgid/django-users/54e68516-af14-41f4-a47b-0088a6ce023d%40googlegroups.com?utm_medium=email&utm_source=footer>.