orizis
orizis

Reputation: 166

Can django filter queryset based on a dictionary field?

I am diving to a django rest-api framework that someone else wrote and configured, and I came across a problem I could not find any good solution for.

There is a model containing field of type "YAMLField". While trying to retrieve this field member, it is converted to OrderedDict (not quite sure how and where this conversion is happening...).

Now, I have a queryset of this model. I understand how to filter a queryset based on simple attributes, but how can I filter it based on this dictionary?

For example, each entry in this queryset (which is MyModel instance) contains:

MyModel.myDictionary == {'firstKey': 'firstVal', 'secondKey':'secondVal}

Now I want to get all the entries from this queryset where:

myDictionary = {'firstKey': 'Something'}

Meaning, my dictionary to filter by, may contain only a subset of the keys.

I could not find any solution or a straight forward way to do it, leading me to iterate the queryset and for each entry, iterate the dictionary. This feels like too much overhead...

Upvotes: 2

Views: 6072

Answers (2)

bet_bit
bet_bit

Reputation: 58

I think I had the same problem and someone told me an straightforward answer, which consists in adding "__{dictionary_key}" to your filtering request such as, in your case:

 Model.objects.all().filter(myDictionary__firstKey="Something")

Though the asnwer is probably coming too late, I post it hoping that it can be useful for others in the future!

Upvotes: 2

M.Void
M.Void

Reputation: 2894

You need this is possible. For more information see django-rest-framework doc

class MultipleFieldLookupMixin(object):
    """
    Apply this mixin to any view or viewset to get multiple field filtering
    based on a `lookup_fields` attribute, instead of the default single field filtering.
    """
    def get_object(self):
        queryset = self.get_queryset()             # Get the base queryset
        queryset = self.filter_queryset(queryset)  # Apply any filter backends
        filter = {}
        for field in self.lookup_fields:
            filter[field] = self.kwargs[field]
        return get_object_or_404(queryset, **filter)  # Lookup the object

Upvotes: 1

Related Questions