You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django后台订单修改视图出现TypeError: __str__返回非字符串问题求助

Django后台订单修改视图触发TypeError问题

问题场景

基于Django 4.2(Python 3.11.3)开发的应用,访问订单对象后台修改视图(URL:http://127.0.0.1:8000/admin/accounts/order/38/change/)时,触发以下错误:

TypeError: str returned non-string (type NoneType)
异常位于django/forms/models.py第1504行,错误回溯显示根源是调用str(obj)时,某个模型的__str__方法返回了NoneType。

相关模型代码

Product模型

class Product(models.Model):
    CATEGORY = (
        ('Residential', 'Residential'),
        ('Commercial', 'Commercial'),
        ('Auto', 'Auto'),
    )

    name = models.CharField(max_length=200, null=True)
    price = models.FloatField(null=True)
    category = models.CharField(max_length=200, null=True, choices=CATEGORY)
    description = models.CharField(max_length=200, null=True, blank=True)
    date_created = models.DateTimeField(auto_now_add=True, null=True)
    tags = models.ManyToManyField(Tag)

    def __str__(self):
        return self.name if self.name is not None else ''

Order模型

class Order(models.Model):
    STATUS = (
        ('Pending', 'Pending'),
        ('Processing', 'Processing'),
        ('Ready to be picked-up', 'Ready to be picked-up'),
        ('Order Rejected', 'Order Rejected'),
    )
    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, null=True)
    status = models.CharField(max_length=200, null=True, choices=STATUS)
    #note = models.CharField(max_length=1000, null=True)
    def __str__(self):
        if self.product:
            return str(self.product)
        return f"No Product (Order #{self.id})"

排查方向

  • 检查目标订单的关联数据:
    登录Django shell(执行python manage.py shell),查询订单#38的详情:

    from accounts.models import Order
    order = Order.objects.get(id=38)
    print("Order product:", order.product)
    print("Product str:", str(order.product) if order.product else "No product")
    print("Customer str:", str(order.customer) if order.customer else "No customer")
    

    重点确认:

    1. 该订单的product是否为None,以及Order.__str__的兜底分支是否正常返回字符串。
    2. 如果product存在,对应的Product实例name字段是否为None,验证Product.__str__的兜底逻辑是否生效。
    3. 检查Customer模型的__str__方法,后台渲染时可能调用该方法,若其存在返回None的情况也会触发错误。
  • 检查Admin配置:
    查看accounts/admin.py中OrderAdmin的配置,确认list_display、fields或readonly_fields里是否包含会触发模型__str__调用的字段,或者自定义显示方法是否存在返回None的情况。

修复建议

1. 加固所有模型的__str__方法

确保所有关联模型(包括Customer)的__str__绝对不会返回None:

  • 优化Product模型的__str__:
    def __str__(self):
        return self.name or 'Unnamed Product'
    
  • 保持Order模型现有逻辑,可优化可读性:
    def __str__(self):
        return str(self.product) if self.product else f"No Product (Order #{self.id})"
    
  • 补充Customer模型的__str__兜底(假设Customer有name字段):
    class Customer(models.Model):
        # 其他字段
        def __str__(self):
            return self.name or 'Anonymous Customer'
    

2. 修复异常订单数据

如果排查发现订单#38的关联数据存在异常(比如关联的Product实例name为None),直接在Django shell中修正:

# 示例:给无名称的Product设置默认值
from accounts.models import Product
prod = Product.objects.get(id=xxx)  # 替换为订单38关联的product_id
prod.name = 'Unnamed Product'
prod.save()

3. 优化Admin表单渲染

若Admin配置存在自定义字段导致错误,修改OrderAdmin的显示逻辑,避免调用可能返回None的方法:

from django.contrib import admin
from .models import Order

class OrderAdmin(admin.ModelAdmin):
    list_display = ('get_product_name', 'customer', 'status', 'date_created')
    
    def get_product_name(self, obj):
        return obj.product.name if (obj.product and obj.product.name) else 'No Product'
    get_product_name.short_description = 'Product'

admin.site.register(Order, OrderAdmin)

内容的提问来源于stack exchange,提问作者Brenn Alexander Navarez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 08:22:00