Douglas Meehan
Douglas Meehan

Reputation: 167

Python/Django Concatenate a string depending on whether that string exists

I'm creating a property on a Django model called "address". I want address to consist of the concatenation of a number of fields I have on my model. The problem is that not all instances of this model will have values for all of these fields. So, I want to concatenate only those fields that have values.

What is the best/most Pythonic way to do this?

Here are the relevant fields from the model:

house = models.IntegerField('House Number', null=True, blank=True)
suf = models.CharField('House Number Suffix', max_length=1, null=True, blank=True)
unit = models.CharField('Address Unit', max_length=7, null=True, blank=True)
stex = models.IntegerField('Address Extention', null=True, blank=True)
stdir = models.CharField('Street Direction', max_length=254, null=True, blank=True)
stnam = models.CharField('Street Name', max_length=30, null=True, blank=True)
stdes = models.CharField('Street Designation', max_length=3, null=True, blank=True)
stdessuf = models.CharField('Street Designation Suffix',max_length=1, null=True, blank=True)

I could just do something like this:

def _get_address(self):
    return "%s %s %s %s %s %s %s %s" % (self.house, self.suf, self.unit, self.stex, self.stdir, self.stname, self.stdes, self.stdessuf)

but then there would be extra blank spaces in the result.

I could do a series of if statements and concatenate within each, but that seems ugly.

What's the best way to handle this situation?

Thanks.

Upvotes: 5

Views: 6024

Answers (3)

cberner
cberner

Reputation: 3040

I'd use a generator to get just the non-Falsy values, and then join them. For example:

parts = (self.house, self.suf, self.unit, self.stex, self.stdir, self.stname, self.stdes, self.stdessuf)
return " ".join(str(s) for s in parts if s is not None)

Upvotes: 2

jdi
jdi

Reputation: 92577

parts = (1, 'a', 'b', 2, 'c', 'd', None, 'f')
# parts = (self.house, self.suf, self.unit, 
#           self.stex, self.stdir, self.stname, 
#           self.stdes, self.stdessuf)
' '.join(str(part) for part in parts if part is not None)
# '1 a b 2 c d e f'

You just do a list comp, and check if any value is not None, and also convert them to a string so they join properly regardless of type.

Upvotes: 4

Maksym Polshcha
Maksym Polshcha

Reputation: 18368

" ".join(filter(None, 
               [self.house, self.suf, self.unit, 
                self.stex, self.stdir, self.stname, 
                self.stdes, self.stdessuf]))

Upvotes: 2

Related Questions