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?
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 in comment:
> if obj.ototoxic_comment:
> comment = "{0}{1}: {2}\n".format(comment,
> obj.substance.name, obj.ototoxic_comment)
> if comment:
> self.ototoxic_comment =
> comment.replace(ellip, "")
> # next of seven text fields in this model and so on
> ...
>
> There are 90 occurrences of this pattern in 18 concat_fields() methods
> in 18 models which are all much the same.
>
> This offends me but I don't know how to start on the necessary "meta"
> programming to make it somewhat more elegant.
>
> Here is the on-screen help text for the user ...
>
> "For mixtures, expandable blank fields "\
> "below will be populated with ingredient data from the same fields. "\
> "Edit as required. To retrieve that data again add an ellipsis (...) "\
> "somewhere in the field and click [Save]"
>
> Any advice would be appreciated. And appreciation might involve red wine.
>
> Thanks
>
> Mike
>
>
> On 7/12/2016 9:38 AM, Mike Dewhirst wrote:
> > Consider a chemical mixture with a bunch of ingredients. Both mixture
> > and ingredients are instances of the same class so they have the same
> > fields. They also have many related models, including 1:1, 1:n and n:m.
> >
> > Each related model will have none or many TextField's.
> >
> > The objective is to programmatically fill empty mixture text fields
> > with concatenated content from the ingredients. The concatenated
> > content would be separated by ingredient name titles for the user to
> > deal with the content more easily.
> >
> > I don't necessarily need all mixture text fields filled this way but
> > it certainly makes sense for some. With a couple of related models I'd
> > concatenate all text fields, with most though I'd like to pick and
> > choose by field name and I'd ignore some models completely.
> >
> > The following model method is working properly as described but it is
> > mostly boiler-plate. It also only covers the first few of a large
> > number of related models with text fields. If I keep using this
> > technique it will add hundreds of LOC. Yuk.
> >
> > The question is how can I refactor this and make it generic? Perhaps
> > using the _meta API?
> >
> > Any guidance appreciated
> >
> >
> > (In the abstract ancestor class of the Solid, Liquid and Gas classes)
> >
> > def concat_fields(self, ingredients):
> > """ ingredients is a queryset of substance-to-substance m2m records.
> > A substance has one physical state object being gas, liquid or solid
> > each of which inherits from core_fields and the fields *here* we
> wish
> > to concatenate text from (at the moment) all come from core_fields.
> > """
> > assert ingredients
> > # populate the list of ingredient physical state objects
> > state_objs = list()
> > for m2m in ingredients:
> > state_objs.append(m2m.ingredient.get_physical_state_object())
> >
> > # get the text concatenated
> > if not self.stability_comment:
> > comment = ""
> > for obj in state_objs:
> > if obj.stability_comment:
> > name = 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
> > 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
> > 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
> > 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
> > text = obj.incompatibilities
> > comment = "{0}\n{1}: {2}".format(comment, name, text)
> > comment = comment.strip()
> > if comment:
> > self.incompatibilities = comment
> >
> > Thanks
> >
> > Mike
> >
> >
>
>
> --
> PLEASE NOTE OUR NEW LANDLINE IS +61 (0) 3 9034 3977
>
> Climate Pty Ltd
> PO Box 308
> Mount Eliza
> Vic 3930
> Australia +61
>
> T: 03 9034 3977
> M: 0411 704 143
>
>
>
--
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 [email protected].
To post to this group, send email to [email protected].
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/54e68516-af14-41f4-a47b-0088a6ce023d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.