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.

Reply via email to