【问题标题】:Django admin: __str__ returned non-string (type int)Django 管理员:__str__ 返回非字符串(int 类型)
【发布时间】:2020-08-15 13:03:36
【问题描述】:

我正在做一个在 Django 中创建 API 的家庭作业。当我单击 Django 管理框架中的链接时,我的两个模型上出现以下错误:

TypeError at /officer/
__str__ returned non-string (type int)

Request Method:     GET
Request URL:    http://127.0.0.1:8000/officer/
Django Version:     3.0.4
Exception Type:     TypeError
Exception Value:    

__str__ returned non-string (type int)

Exception Location:     /usr/local/lib/python3.7/dist-packages/rest_framework/relations.py in display_value, line 221
Python Executable:  /usr/bin/python3
Python Version:     3.7.5
Python Path: 

Error during template rendering

In template /usr/local/lib/python3.7/dist-packages/rest_framework/templates/rest_framework/horizontal/select.html, error at line 15
__str__ returned non-string (type int)

我的其他模型似乎工作正常。以下是 models.py 中的一些代码:

class Subscriber(models.Model):
    subscriberID = models.IntegerField(primary_key=True)
    username = models.ForeignKey(UserInfo, on_delete=models.CASCADE)
    subscriptiontypecode = models.ForeignKey(SubscriptionType, on_delete=models.CASCADE)
    servicecode = models.ForeignKey(Service, on_delete=models.CASCADE)
    requestdate = models.DateField()
    startdate = models.DateField()
    enddate = models.DateField()
    motifofcancellation = models.CharField(max_length=64)
    beneficiaryID = models.IntegerField()

    def __str__(self):
        return self.subscriberID

class TransferredSubscription(models.Model):
    transferID = models.IntegerField(primary_key=True)
    transferfrom = models.CharField(max_length=64)
    transferto = models.CharField(max_length=64)
    requestdate = models.DateField()
    transferdate = models.DateField()
    subscriberID = models.ForeignKey(Subscriber, on_delete=models.CASCADE)

    def __str__(self):
        return self.transferID

class Officer(models.Model):
    officecode = models.ForeignKey(Office, on_delete=models.CASCADE)
    subscriberID = models.ForeignKey(Subscriber, on_delete=models.CASCADE)
    startdate = models.DateField()
    enddate = models.DateField()

    def __str__(self):
        return self.officecode

TransferredSubscription 工作正常。我尝试添加 return str(self.officecode) 并且仍然给出相同的错误。

任何见解为什么会发生这种情况?

编辑:为每个请求添加错误回溯:

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/officer/

Django Version: 3.0.4
Python Version: 3.7.5
Installed Applications:
['synerd',
 'backend',
 'rest_framework',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']


Template error:
In template /usr/local/lib/python3.7/dist-packages/rest_framework/templates/rest_framework/horizontal/select.html, error at line 15
   __str__ returned non-string (type int)
   5 :     <label class="col-sm-2 control-label {% if style.hide_label %}sr-only{% endif %}">
   6 :       {{ field.label }}
   7 :     </label>
   8 :   {% endif %}
   9 : 
   10 :   <div class="col-sm-10">
   11 :     <select class="form-control" name="{{ field.name }}">
   12 :       {% if field.allow_null or field.allow_blank %}
   13 :         <option value="" {% if not field.value %}selected{% endif %}>--------</option>
   14 :       {% endif %}
   15 :        {% for select in field.iter_options %} 
   16 :           {% if select.start_option_group %}
   17 :             <optgroup label="{{ select.label }}">
   18 :           {% elif select.end_option_group %}
   19 :             </optgroup>
   20 :           {% else %}
   21 :             <option value="{{ select.value }}" {% if select.value|as_string == field.value|as_string %}selected{% endif %} {% if select.disabled %}disabled{% endif %}>{{ select.display_text }}</option>
   22 :           {% endif %}
   23 :       {% endfor %}
   24 :     </select>
   25 : 


Traceback (most recent call last):
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/core/handlers/base.py", line 145, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/core/handlers/base.py", line 143, in _get_response
    response = response.render()
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/response.py", line 105, in render
    self.content = self.rendered_content
  File "/usr/local/lib/python3.7/dist-packages/rest_framework/response.py", line 70, in rendered_content
    ret = renderer.render(self.data, accepted_media_type, context)
  File "/usr/local/lib/python3.7/dist-packages/rest_framework/renderers.py", line 724, in render
    context = self.get_context(data, accepted_media_type, renderer_context)
  File "/usr/local/lib/python3.7/dist-packages/rest_framework/renderers.py", line 696, in get_context
    'post_form': self.get_rendered_html_form(data, view, 'POST', request),
  File "/usr/local/lib/python3.7/dist-packages/rest_framework/renderers.py", line 511, in get_rendered_html_form
    return self.render_form_for_serializer(serializer)
  File "/usr/local/lib/python3.7/dist-packages/rest_framework/renderers.py", line 521, in render_form_for_serializer
    {'style': {'template_pack': 'rest_framework/horizontal'}}
  File "/usr/local/lib/python3.7/dist-packages/rest_framework/renderers.py", line 372, in render
    return template.render(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/base.py", line 171, in render
    return self._render(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/base.py", line 936, in render
    bit = node.render_annotated(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/base.py", line 903, in render_annotated
    return self.render(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/defaulttags.py", line 209, in render
    nodelist.append(node.render_annotated(context))
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/base.py", line 903, in render_annotated
    return self.render(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/defaulttags.py", line 309, in render
    return nodelist.render(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/base.py", line 936, in render
    bit = node.render_annotated(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/base.py", line 903, in render_annotated
    return self.render(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/library.py", line 192, in render
    output = self.func(*resolved_args, **resolved_kwargs)
  File "/usr/local/lib/python3.7/dist-packages/rest_framework/templatetags/rest_framework.py", line 87, in render_field
    return renderer.render_field(field, style)
  File "/usr/local/lib/python3.7/dist-packages/rest_framework/renderers.py", line 351, in render_field
    return template.render(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/base.py", line 171, in render
    return self._render(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/base.py", line 936, in render
    bit = node.render_annotated(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/base.py", line 903, in render_annotated
    return self.render(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/defaulttags.py", line 161, in render
    values = self.sequence.resolve(context, ignore_failures=True)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/base.py", line 670, in resolve
    obj = self.var.resolve(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/base.py", line 795, in resolve
    value = self._resolve_lookup(context)
  File "/home/ubuntu/.local/lib/python3.7/site-packages/django/template/base.py", line 857, in _resolve_lookup
    current = current()
  File "/usr/local/lib/python3.7/dist-packages/rest_framework/relations.py", line 215, in iter_options
    self.get_choices(cutoff=self.html_cutoff),
  File "/usr/local/lib/python3.7/dist-packages/rest_framework/relations.py", line 202, in get_choices
    for item in queryset
  File "/usr/local/lib/python3.7/dist-packages/rest_framework/relations.py", line 202, in <listcomp>
    for item in queryset
  File "/usr/local/lib/python3.7/dist-packages/rest_framework/relations.py", line 221, in display_value
    return str(instance)

Exception Type: TypeError at /officer/
Exception Value: __str__ returned non-string (type int)

编辑 2:添加更多代码 视图.py

class SubscriberView(viewsets.ModelViewSet):
    queryset = Subscriber.objects.all()
    serializer_class = SubscriberSerializer

class TransferredSubscriptionView(viewsets.ModelViewSet):
    queryset = TransferredSubscription.objects.all()
    serializer_class = TransferredSubscriptionSerializer

class OfficerView(viewsets.ModelViewSet):
    queryset = Officer.objects.all()
    serializer_class = OfficerSerializer

urls.py

router.register('subscriber', views.SubscriberView)
router.register('transferredsubscription', views.TransferredSubscriptionView)
router.register('officer', views.OfficerView)

admin.py

admin.site.register(Subscriber)
admin.site.register(TransferredSubscription)
admin.site.register(Officer)

序列化器.py

class SubscriberSerializer(serializers.ModelSerializer):
    class Meta:
        model = Subscriber
        fields = '__all__'

class TransferredSubscriptionSerializer(serializers.ModelSerializer):
    class Meta:
        model = TransferredSubscription
        fields = '__all__'

class OfficerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Officer
        fields = '__all__'

【问题讨论】:

  • 可以显示对应的视图吗?
  • 添加了一些来自views.py、urls.py、admin.py、serializers.py的sn-ps
  • 返回 str(self.transferId) 并将整数转换为字符串。
  • 为什么要在对象上定义这样的 str 方法呢?您是否以某种方式依赖该行为,以及 ID 为“None”的新对象会发生什么?
  • @AndrewBacker 我浏览并注释掉了订户和办公室模型上的 def __str__(self): ,但仍然遇到同样的问题......然后我对我的所有模型都做了这个,现在一切正常 - 谢谢!

标签: python django python-3.x django-models django-rest-framework


【解决方案1】:

您尚未向我们展示您的 Office 模型。由于officecodeOffice 对象,请确保您已在Office 模型中定义了__str__() 方法。您可以将其转换为 int 以防万一。

class Office(models.Model):
    officecode = models.IntegerField(primary_key=True)
    ....
    def __str__(self):
        return str(self.officecode)

The str() method is called whenever you call str() on an object.

【讨论】:

    【解决方案2】:

    回应你的 cmets:

    仅从堆栈跟踪中查看源代码,我无法确切说明为什么会出现问题。另一个答案提到在pk上调用str,但这没有用。要调试它,您需要在发生异常的地方放置一个断点,并沿着堆栈跟踪查看值是什么。

      File "/usr/local/lib/python3.7/dist-packages/rest_framework/relations.py", line 221, in display_value
        return str(instance)
    

    我最好的猜测是它会返回一个看起来像数字的东西,并引发错误。

    1) 尝试删除模型的所有 __str__ 实现。并不是真的需要,因为基类做得足够好,除非你想让它更具吸引力

    2) 尝试在其中返回多个 str(int),以免被误解:

    def __str__(self):
        return "%s(%s)" % (self.__class__.__name__, self.pk)
    

    我在 django 或 drf 的任何地方都找不到这个特定的错误,所以如果不直接调试它,我就没有建议了。

    【讨论】:

      【解决方案3】:

      您的 Subscriber.__str__ 也返回一个 int。改变:

      def __str__(self):
          return self.subscriberID
      

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

      【讨论】:

        猜你喜欢
        • 2017-07-02
        • 1970-01-01
        • 2017-03-29
        • 2018-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-27
        • 1970-01-01
        相关资源
        最近更新 更多