管理员错误:__str__ 返回非字符串(NoneType 类型)

Posted

技术标签:

【中文标题】管理员错误:__str__ 返回非字符串(NoneType 类型)【英文标题】:Error in admin: __str__ returned non-string (type NoneType) 【发布时间】:2017-07-02 23:10:15 【问题描述】:

管理员在尝试将实例添加到我的一个模型时返回此错误。模型本身有一个正确的 str() 方法并且还没有包含任何实例。还尝试用静态方法替换 str() 方法或完全删除它。没有运气。

该错误似乎表明管理员的历史记录部分出现了问题。 Stacktrace 指向第 33 行。

Error during template rendering

In template /Users/snirp/juis/snirpdrive/glotto/venv/lib/python3.6/site-packages/django/contrib/admin/templates/admin/change_form.html, error at line 33
__str__ returned non-string (type NoneType)
23  % endblock %
24  % endif %
25  
26  % block content %<div id="content-main">
27  % block object-tools %
28  % if change %% if not is_popup %
29    <ul class="object-tools">
30      % block object-tools-items %
31      <li>
32          % url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %
33          <a href="% add_preserved_filters history_url %" class="historylink">% trans "History" %</a>
34      </li>
35      % if has_absolute_url %<li><a href=" absolute_url " class="viewsitelink">% trans "View on site" %</a></li>% endif %
36      % endblock %
37    </ul>
38  % endif %% endif %
39  % endblock %
40  <form % if has_file_field %enctype="multipart/form-data" % endif %action=" form_url " method="post" id=" opts.model_name _form" novalidate>% csrf_token %% block form_top %% endblock %
41  <div>
42  % if is_popup %<input type="hidden" name=" is_popup_var " value="1" />% endif %
43  % if to_field %<input type="hidden" name=" to_field_var " value=" to_field " />% endif %

这些是我的models.pyadmin.py的相关部分

class UserContent(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    created_by = models.ForeignKey(User, related_name='%(class)s_creator')
    updated_by = models.ForeignKey(User, related_name='%(class)s_updater')

    class Meta:
        abstract = True


class Linetrans(UserContent):
    line = models.ForeignKey(Line)
    translation = models.ForeignKey(Translation)
    text = models.CharField(max_length=400)

    #def __str__(self):
    #    return self.text

    class Meta:
        ordering = ['line']

admin.site.register(Linetrans)

其他模型类非常相似,不会返回错误。当 Linetrans 作为内联添加到另一个管理类时也会发生错误。

编辑/更新:我注释掉了模型中的所有其他 str() 方法,果然错误似乎消失了。现在正试图查明问题。

【问题讨论】:

【参考方案1】:

原来在相关模型中有一个意外的空 CharField。留下这个答案,因为它可能对其他人有所帮助。

解决问题,系统地注释掉模型的__str__() 方法,直到找到有问题的模型。从那里开始识别违规记录。

【讨论】:

我有一个 str 方法返回 self.title 而不是 self.title or '' 我刚刚在 irc 上花了一个小时来了解 Seth 的解决方案。 +1 我认为您仍然应该尝试找到违规对象。 这很有帮助。不知道错误在哪里,看到这个答案并更改了self.name to self.name or ' ' 并且完全有效。非常感谢。 有一个类似的问题——用on_delete=models.SET_DEFAULT, default=None, null=True修改了一个模型,这破坏了管理界面的__str__。使用@seth 方法:return self.NAME or '' 解开了谜团。 我有 __str__ 返回 self.data(JSON 信息)而不是 str(self.data)【参考方案2】:

我遇到了类似的问题。问题是一行的主键为空(我不知道这是怎么发生的)。由于级联问题,我无法删除该行。所以我不得不把 str 方法改成这样。

def __str__(self):
    if self.customerName==None:
        return "ERROR-CUSTOMER NAME IS NULL"
    return self.customerName

【讨论】:

谢谢。我在其他地方引用的列之一中添加了一个带有 NULL 的测试行。删除测试行解决了问题。【参考方案3】:

查看您在

中提到的类
        models.ForeignKey 

问题出在

        __str__() 

这些类之一的方法。 然后,添加

                             or ''

在该类的返回语句中像这样。

        def __str__(self):
            return self.title or ''

【讨论】:

【参考方案4】:
def __str__(self):
        return str(self.topic)

使用 str 使其键入字符串。 那么就不是非字符串类型了。

【讨论】:

【参考方案5】:

对于这个错误,你可以使用两种解决方案

第一种解决方案:你可以在代码下面注释掉

 def __str__(self):
    return self.id

 #def __str__(self):
 #  return self.id

第二种解决方案:可以从对象中返回字符串

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

【讨论】:

【参考方案6】:

您还可以从 django shell python manage.py shell 中删除模型中导致此问题的实例。当您处理一个包含许多相关模型(如我的模型)的模型时,这会有所帮助。

此问题通常是由更改模型字段和 迁移,使得实例彼此不兼容 及相关领域

【讨论】:

【参考方案7】:

如果您尝试使用 __str__() 返回 ForeignKeyOneToOneField 的值,则会返回错误

例子:

def __str__():
    return self.user  # where user is a key to other model class

应该是:

def __str__():
    return self.user.__str__() 
    # Or basically any other way that would explicitly unbox the value inside the related model class.

【讨论】:

【参考方案8】:

在我的情况下,我遇到了同样的问题,其根源是:对于 __str__ 函数中使用的字段,在数据库中保存了空值。

所以我可以通过以下方式解决问题:

update table
set field_for_STR_use = 'any value'
where field_for_STR_use is null or field_for_STR_use = ''

之后,我只刷新了视图,问题就消失了。

【讨论】:

【参考方案9】:

有一个外部引用返回非字符串字段。我将其更改为字符串字段,或者您可以更改为 str(foreign-key-return-element) name = models.CharField(max_length=200, unique=True) # 文章名称 parent = models.ForeignKey('self',on_delete=models.DO_NOTHING,related_name='category_parent_item', default=None, null=True) # 存储子项 created_at = models.DateTimeField(auto_now=True) # 创建日期 updated_at = models.DateTimeField(auto_now=True) # 更新日期 user = models.ForeignKey(get_user_model(),

on_delete=models.DO_NOTHING,related_name='category_update_user', default=None, null=True) #更新文章的用户

def __str__(self):
    return self.name ----------> this was an integer field initially in foreign reference

【讨论】:

【参考方案10】:

这对我有用:

    def __str__(self):
    return f"self.category"

只需使用“f”字符串

【讨论】:

【参考方案11】:

就我而言,我有一个不同的模型,它被另一个模型调用,该模型具有来自 VSCode 的默认 sn-p 为:

def __str__(self):
    return

这是导致错误的原因,即使它在日志中的其他位置显示也是如此。

【讨论】:

以上是关于管理员错误:__str__ 返回非字符串(NoneType 类型)的主要内容,如果未能解决你的问题,请参考以下文章

如果 t.__str__() 返回一个非字符串而不是 print(t.__str__()),为啥 print(t) 会出错?

Django-Factoryboy:带有字符串格式的__str__调用改为返回对象

为啥 len(None) 不返回 0?

python调用mysql中的自定义变量,为啥返回的值都是None

python 上下文管理总结

Python re模块 正则表达式