Search code examples
djangotemplatesforeign-keys

How to avoid a NonType error in template when using ForeignKey in Model?


I want to access the region of the user in my template:

{% if object.seller.profile.post_code %}{{ object.seller.profile.post_code }} {% endif %}{% if object.seller.profile.city%}{{ object.seller.profile.city }}<br/>{% endif %}

{% if object.seller.profile.region.name %}{{ object.seller.profile.region.name }}, {% endif %}{% if object.seller.profile.region.country.name %}{{  object.seller.profile.region.country.name }}{% endif %}

This is my model:

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    image = models.ImageField(default='default.jpg', upload_to='profile_pics',
            verbose_name='Profilbild')
    post_code = models.CharField(max_length=5, blank=True, verbose_name='Postleitzahl')
    region = models.ForeignKey(Region, on_delete=models.CASCADE,
             null=True, blank=True, verbose_name='Region', help_text='Bundesland oder Kanton')
    city = models.CharField(max_length=50, blank=True, verbose_name='Stadt')
    street = models.CharField(max_length=50, blank=True, verbose_name='Straße')

class Region(models.Model):
    name = models.CharField(max_length=30, verbose_name='Region', help_text='Bundesland oder Kanton', default='Berlin')
    symbol = models.CharField(max_length=30, verbose_name='Region-Kürzel', default='BER')
    country = models.ForeignKey('Country', on_delete=models.CASCADE, null=True,
                               verbose_name='Land', default=0)

class Country(models.Model):
    name = models.CharField(max_length=30, verbose_name='Land', default='Deutschland')
    symbol = models.CharField(max_length=4, verbose_name='Kürzel', default='DE')

But I don't want to force the user to enter their adress data. But if the ForeignKey-Fields are not filled I get

    'NoneType' object has no attribute 'country'

Is there a more a elegant way than checking each field if it is filled in the views.py and adding it separately to the context?


Solution

  • Can add some shortcuts to your Profile model to help with this:

    views.py:

    class Profile(models.Model):
    
        ...
    
        @property
        def country_name(self): 
             return self.region.country.name if self.region and self.region.country else None
    

    template.html:

    ...
    <div> {{object.seller.profile.country_name }} </div>