简体   繁体   中英

Django admin: __str__ returned non-string (type int)

I'm working on a homework assignment to create an API in Django. I am getting the following error on two of my models when I click the link in the Django admin framework:

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)

My other models appear to be working correctly. Here is some code from 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 works fine. I tried adding return str(self.officecode) and that still gives the same error.

Any insight why this may be happening?

EDIT: Adding the error traceback per request:

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)

EDIT 2: Adding some more code views.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)

serializers.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__'

You haven't shown us your Office model. Since officecode is an Office object, make sure you have defined the __str__() method in Office model. You could cast it to an int just in case.

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.

Responding to your comments:

I can't tell exactly why the problem is happening from the stack trace alone, looking at the source code. The other answer mentions calling str on the pk, but that didn't work. To debug it you'd need to put a breakpoint where the exception happens and walk up the stack trace to see what the values are.

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

My best guess is that its getting back something that looks like a number, and raising an error.

1) Try removing all __str__ implementations for models. The aren't really needed since the base class does something good enough, unless you want to make it more attractive

2) Try returning more than a str(int) in there, so it can't be misinterpreted:

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

I can't find this specific error anywhere in django or drf, so without debugging it directly I'm out of suggestions.

your Subscriber.__str__ returns an int as well. change:

def __str__(self):
    return self.subscriberID

to

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM