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 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/bec9120a-1a8a-2e1a-768f-3f7ab2a9f2dc%40dewhirst.com.au.
For more options, visit https://groups.google.com/d/optout.

Reply via email to