Ejemplo n.º 1
0
def resolve_field(model_field, lookup_expr):
    """
    Resolves a ``lookup_expr`` into its final output field, given
    the initial ``model_field``. The lookup expression should only contain
    transforms and lookups, not intermediary model field parts.

    Note:
    This method is based on django.db.models.sql.query.Query.build_lookup

    For more info on the lookup API:
    https://docs.djangoproject.com/en/1.9/ref/models/lookups/

    """
    query = model_field.model._default_manager.all().query
    lhs = Expression(model_field)
    lookups = lookup_expr.split(LOOKUP_SEP)

    assert len(lookups) > 0

    while lookups:
        name = lookups[0]
        # If there is just one part left, try first get_lookup() so
        # that if the lhs supports both transform and lookup for the
        # name, then lookup will be picked.
        if len(lookups) == 1:
            final_lookup = lhs.get_lookup(name)
            if not final_lookup:
                # We didn't find a lookup. We are going to interpret
                # the name as transform, and do an Exact lookup against
                # it.
                lhs = query.try_transform(lhs, name, lookups)
                final_lookup = lhs.get_lookup('exact')
            return lhs.output_field, final_lookup.lookup_name
        lhs = query.try_transform(lhs, name, lookups)
        lookups = lookups[1:]
def lookups_for_field(model_field):
    """
    Generates a list of all possible lookup expressions for a model field.
    """
    lookups = []

    for expr, lookup in model_field.get_lookups().items():
        if issubclass(lookup, Transform):
            transform = lookup(Expression(model_field))
            lookups += [
                LOOKUP_SEP.join([expr, sub_expr]) for sub_expr
                in lookups_for_transform(transform)
            ]

        else:
            lookups.append(expr)

    return lookups
def lookups_for_field(model_field):
    """
    Generates a list of all possible lookup expressions for a model field.
    """
    # This is a hack to work around:
    # https://github.com/django/django/pull/6906
    if isinstance(model_field, ForeignObject):
        return ['exact', 'gt', 'gte', 'lt', 'lte', 'in', 'isnull']

    lookups = []

    for expr, lookup in six.iteritems(class_lookups(model_field)):
        if issubclass(lookup, Transform) and django.VERSION >= (1, 9):
            transform = lookup(Expression(model_field))
            lookups += [
                LOOKUP_SEP.join([expr, sub_expr]) for sub_expr
                in lookups_for_transform(transform)
            ]

        else:
            lookups.append(expr)

    return lookups