Search code examples
djangodjango-modelsdjango-admin

TypeError at /admin/accounts/order/add/ (__str__ returned non-string (type Customer))


I wanted to use many to many and many to one with Django. Then I write this codes but when I try to add an Order from Admin Panel I got this error and I cannot find the solution. I hope someone can help me. In the below I share my models.py file I hope it will enough.

from django.db import models

# Create your models here.

class Customer(models.Model):
    name = models.CharField(max_length=200, null=True)
    phone = models.IntegerField(null=True)
    email = models.EmailField(null=True)
    date_created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name
    
class Tag(models.Model):
    name=models.CharField(max_length=200, null=True)
    def __str__(self):
        return self.name
    
class Product(models.Model):
    STATUS = (
        ('Indoor','Indoor'),
        ('Out Door', 'Out Door')
    )
    name = models.CharField(max_length=200, null=True)
    price = models.FloatField(null=True)
    category = models.CharField(max_length=200, null=True,choices=STATUS)
    description = models.CharField(max_length=200, null=True, blank=True)
    date_created = models.DateTimeField(auto_now_add=True)
    tags = models.ManyToManyField(Tag)

    def __str__(self):
        return self.name

class Order(models.Model):
    STATUS = (
        ('Pending','Pending'),
        ('Out for deliver', 'Out for delivery'),
        ('Delivered', 'Delivered')
    )
    customer = models.ForeignKey(Customer, null=True, on_delete=models.SET_NULL)
    product = models.ForeignKey(Product, null=True, on_delete=models.SET_NULL)
    date_created = models.DateTimeField(auto_now_add=True)
    status = models.CharField(max_length=200, null=True, choices=STATUS)

    def __str__(self):
        return self.customer

I'm watching Dennis Ivy's Django Crash Course Tutorials and I did exactly what he did but he didn't get this error and I wonder what's the problem more than the solution. I read some tutorial about Many to one and Many to Many but I got nothing.


Solution

  • The __str__ method should return a string

    Unfortunately, your Order __str__ method, returns a customer object.

    def __str__(self):
        return self.customer
    

    To fix this, just name it return a string instead, eg,

    def __str__(self):
        return f"Order: {self.product.name} for {self.customer.name}"
        # use return "Order: " + self.product.name + " for " + self.customer.name for older python versions
    

    You should be able to also use

    def __str__(self):
        return str(self.customer) 
    

    to access the customer objects __str__ function directly.