2

I have been calling the same model over and over again but somethings with different field but there would be a few that would always be the same. I am thinking if there is a way to refactor it?

For example.

def x(get_filter, **kwargs):
    # if blah 
    return User.object.get(is_active=True, is_deleted=False, is_staff=False, **kwargs)
    # if blah 
    return User.object.filter(is_active=True, is_deleted=False, is_staff=False, **kwargs)
    # if blah 
    return User.object.get(is_active=True, is_deleted=False, **kwargs)
    # if blah 
    return User.object.get(is_active=True, is_deleted=False, is_staff=False, is_superuser=True, **kwargs)

as can be seen, is_active=True and is_deleted=False is always being used. I thought of doing something like

is_deleted = {'is_deleted': False}
is_active = {'is_active': True}
    User.object.filter( is_staff=False, **is_active, **is_deleted,**kwargs)

in my IDE, it would say duplicate ** is not allowed

Can someone give me an idea?

Thanks in advance

Tsuna
  • 2,098
  • 6
  • 24
  • 46

4 Answers4

2

Sure, try this instead

options = {'is_deleted': False,
           'is_active': True}

kwargs.update(options)
User.object.filter(is_staff=False, **kwargs)
NS0
  • 6,016
  • 1
  • 15
  • 14
  • if for some reason that I want to override the `is_deleted` is it possible? – Tsuna May 05 '17 at 21:20
  • Yeah, you can override it after the update call using kwargs["is_deleted"] = True. Since it's a dictionary. – NS0 May 05 '17 at 21:27
1

If you are using Python 3, this would indeed be allowed:

>>> def f(*a, **kwargs): pass
...
>>> a = {'a':1}
>>> b = {'b':2}
>>> f(**a, **b) # No problem!

Let us keep in mind, first of all, that kwargs is simply a dictionary: there is no magic about it. If you have default kwargs, you can put them in another (single!) dictionary:

additional_kwargs = {'is_deleted': False, 'is_active': True}

Now, we have two dictionaries, and it's a simple question of combining them: How to merge two Python dictionaries in a single expression?

We can do this in place:

kwargs.update(additional_kwargs)

And then call the function as normal:

User.object.filter(is_staff=False, **kwargs)
Community
  • 1
  • 1
brianpck
  • 8,084
  • 1
  • 22
  • 33
0

Maybe you can create a new dictionary with the values you want based on your conditions and pass to filter. Se if something like this solves your problem:

should_delete = True if BLAH else False # your condition here
new_kwargs = dict(**kwargs, is_staff=False, is_deleted = should_delete)
return User.object.filter(**new_kwargs)
DSLima90
  • 2,680
  • 1
  • 15
  • 23
0

You can use Python's functool.partial

from functools import partial
def x(get_filter, **kwargs):
    common_invocation = partial(User.object.get, is_active=True, is_deleted=False)
    # if blah 
    return common_invocation(is_staff=False, **kwargs)
    # if blah 
    return User.object.filter(is_active=True, is_deleted=False, is_staff=False, **kwargs)
    # if blah 
    return common_invocation(**kwargs)
    # if blah 
    return common_invocation(is_staff=False, is_superuser=True, **kwargs)

I left your User.object.filter as such. You should get the idea from this.

gipsy
  • 3,859
  • 1
  • 13
  • 21