Search code examples
pythonruby-on-railsdjangovalidationlanguage-comparisons

Equivalent of .presence in Python


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


Solution

  • 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.