Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

__str__ returned non-string (type Bottle), why?

I have a Django project with the following models:

class Ingredient(models.Model):
    drink = models.ForeignKey(DrinkRecipe, on_delete=models.CASCADE)
    ingredient_rhum = models.ForeignKey(Bottle, on_delete=models.CASCADE, null=True, blank=True)
    ingredient_name = models.CharField(max_length=255, blank=True)
    ingredient_amount = models.DecimalField(decimal_places=1,max_digits=5, validators=[MinValueValidator(0.01)])
    

    def __str__(self):
            if self.ingredient_rhum:
                return self.ingredient_rhum
            return self.ingredient_name
        
    def get_absolute_url(self):
        return self.drink.get_absolute_url()

and:

class Bottle(models.Model):
    bottle_name = models.CharField(max_length=255, blank=False, verbose_name='Name')
    bottle_slug = models.SlugField(unique=True, blank=True, null=True)
    bottle_info = HTMLField(blank=False, verbose_name='Information about the bottle')
    bottle_tastingnotes_text = HTMLField(verbose_name='Tasting description', blank=False)
    bottle_tasting_notes = HTMLField(verbose_name='Tasting notes', blank=False)
    bottle_tastingnotes_finish = HTMLField(verbose_name='Finish',blank=False)
    bottle_image = models.ImageField(upload_to=image_upload_handler)
    sorting_number = models.IntegerField()
    bottle_abv = models.DecimalField(max_digits=3,decimal_places=1, verbose_name='ABV', validators=[MinValueValidator(0.01)])
    img_location = 'bottles'
    
    def __str__(self):
        return self.bottle_name
    
    class Meta:
        ordering = ['sorting_number', 'bottle_name']

    def get_bottle_link(self):
        return reverse('rhumSite:drinkBottle',kwargs={'tag':self.bottle_name} )
    
    def get_edit_link(self):
        return reverse('rhumSite:edit_bottle',kwargs={'id':self.id})
    
    def save(self, *args, **kwargs):
        abv = str(self.bottle_abv)
        if not self.id:
            # Newly created object, so set slug
            self.bottle_slug = slugify(self.bottle_name + abv)

        super(Bottle, self).save(*args, **kwargs)

It all works fine when I use them in my CreateView with an inline-modelset-factory.
However: when I try to add an ingredient in my Admin or try to delete an ingredient or an other object that has a ForeignKey with the Bottle model I get the following error:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

__str__ returned non-string (type Bottle)

What did I do wrong and how do I fix it?

>Solution :

You return ingredient_rhum, which is a Bottle, not a string, the __str__ should return a string. You can convert the Bottle to a string:

class Ingredient(models.Model):
    # …

    def __str__(self):
        if self.ingredient_rhum:
            return str(self.ingredient_rhum)
        return self.ingredient_name
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading