Equivalent of .presence in Python

689 Views Asked by At

So, I've been using Ruby on Rails for some time, and I'm wondering if there is something like .presence in Python/Django.

Presence returns the receiver if it is present otherwise returns nil.

object.presence is equivalent to:

object.present? ? object : nil

For example, something like:

state   = params[:state]   if params[:state].present?
country = params[:country] if params[:country].present?
region  = state || country || 'US'
becomes

region = params[:state].presence || params[:country].presence || 'US'

Anthony

2

There are 2 best solutions below

1
sleblanc On BEST ANSWER

In Python, you can achieve this by doing the following, assuming params is a dict:

state = params.get('state')
country = params.get('country')
region = 'US' if (state and country) else None

The method dict.get(key) will return the value associated to the key that has been passed. If no such key exists, it returns None.

If you need to replace the empty values with actual empty strings, you may do this instead:

state = params.get('state', '')
country = params.get('country', '')
region = 'US' if (state and country) else ''

Overall, the "Pythonic" way of doing this is to use a Form:

class Address(Model):
    state = ...
    country = ...
    region = ...

AddressForm = modelform_factory(Address)

#inside view
def view(request):
    if request.method == 'POST':
        form = AddressForm(request.POST, request.FILES)

        if form.is_valid():
            address = form.save(commit=False)
            address.region = 'US' if address.state and address.country
            address.save()

By creating a custom AddressForm class you can do this processing automatically on the instance before saving it. This is the precise role of Form classes.

0
user355166 On

The accepted answer is incorrect.

The ruby version translated to python is roughly (except for truthiness edge cases):

region = params.get('state') or params.get('country') or 'US'

sleblancs answer instead sets the region to 'US' if state and country is set. Completely different.