Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sample edit form - some selection widgets empty #1477

Merged
merged 24 commits into from
Nov 27, 2019
Merged

Sample edit form - some selection widgets empty #1477

merged 24 commits into from
Nov 27, 2019

Conversation

xispa
Copy link
Member

@xispa xispa commented Nov 22, 2019

Description of the issue/feature this PR addresses

This Pull Request adds a generic way to handle search filters in reference widgets for those fields that can be bound to a Client object. There are some content types that can be created inside Clients or associated to them through a ReferenceField. When user (regardless of her role) is inside a Client, Batch or Sample context, the results of searches for these objects must contain not only the global objects (from setup level), but also those that only belong to the client.

Linked issue: #1476

Current behavior before PR

Searches in reference widgets for content types that might be associated to Client were not working properly (only those associated to Client were displayed).

Desired behavior after PR is merged

Seraches in reference widgets for content types that might be associated to Client are working correctly (both global and those associated to client are displayed).

--
I confirm I have tested this PR thoroughly and coded it according to PEP8
and Plone's Python styleguide standards.

@xispa xispa added the Bug 🐞 label Nov 22, 2019
@xispa xispa requested a review from ramonski November 22, 2019 21:40
"""Return the list of portal types from the query passed-in
"""
portal_types = query.get("portal_type", [])
if isinstance(portal_types, basestring):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return obj.getClientUID()
elif api.is_portal(obj):
return None
return self.get_client_uid(obj.aq_parent)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this approach is too explicit. I would rather do a recursive acquisition chain traverser which goes up and calls the IClientUIDAdapter to retrieve either the UID of the object (if the object provides IClient) or get the UID from the schema field.
Anyhow, the Adapter would be responsible to get either the UID or return None or raise StopTraversal (maybe) to terminate the traversal.

@ramonski
Copy link
Contributor

More or less I have this in my mind:

def _chain(object):
    """Generator to walk the acquistion chain of object, considering that it
    could be a function.
    """

    # Walk up the acquisition chain of the object, to be able to check
    # each one for IWorkspace.

    # If the thing we are accessing is actually a bound method on an
    # instance, then after we've checked the method itself, get the
    # instance it's bound to using im_self, so that we can continue to
    # walk up the acquistion chain from it (incidentally, this is why we
    # can't juse use aq_chain()).

    context = aq_inner(object)

    while context is not None:
        yield context

        func_object = getattr(context, 'im_self', None )
        if func_object is not None:
            context = aq_inner(func_object)
        else:
            # Don't use aq_inner() since portal_factory (and probably other)
            # things, depends on being able to wrap itself in a fake context.
            context = aq_parent(context)

def clientfinder(context):
    """
    Return the client

    This walks the acquisition chain up until we find
    something which provides IClient.
    """
    for obj in _chain(context):
        if IClient.providedBy(obj):
            return obj

    return None

Copy link
Contributor

@ramonski ramonski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good PR! 👍

@ramonski ramonski merged commit 226b52c into master Nov 27, 2019
@ramonski ramonski deleted the i1476 branch November 27, 2019 13:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

2 participants