Je travaille sur un devoir pour créer une API dans Django. J'obtiens l'erreur suivante sur deux de mes modèles lorsque je clique sur le lien dans le framework d'administration Django:
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__'
Mes autres modèles semblent fonctionner correctement. Voici un code de models.py:
admin.site.register(Subscriber) admin.site.register(TransferredSubscription) admin.site.register(Officer)
TransferredSubscription fonctionne bien. J'ai essayé d'ajouter return str (self.officecode) et cela donne toujours la même erreur.
Une idée pourquoi cela peut se produire?
EDIT: Ajout du suivi des erreurs par requête:
router.register('subscriber', views.SubscriberView)
router.register('transferredsubscription', views.TransferredSubscriptionView)
router.register('officer', views.OfficerView)
EDIT 2: Ajout de plus de 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
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)
admin.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
serializers.py
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)
3 Réponses :
Vous ne nous avez pas montré votre modèle Office . Étant donné que officecode est un objet Office , assurez-vous d'avoir défini la __str__() dans le modèle Office . Vous pouvez le convertir en un int au cas où.
class Office(models.Model):
officecode = models.IntegerField(primary_key=True)
....
def __str__(self):
return str(self.officecode)
La méthode str () est appelée chaque fois que vous appelez str () sur un objet.
Répondre à vos commentaires:
Je ne peux pas dire exactement pourquoi le problème se produit à partir de la seule trace de la pile, en regardant le code source. L'autre réponse mentionne appeler str sur le pk, mais cela n'a pas fonctionné. Pour le déboguer, vous devez placer un point d'arrêt à l'endroit où l'exception se produit et remonter la trace de la pile pour voir quelles sont les valeurs.
def __str__(self):
return "%s(%s)" % (self.__class__.__name__, self.pk)
Ma meilleure hypothèse est qu'il récupère quelque chose qui ressemble à un nombre et génère une erreur.
1) Essayez de supprimer toutes les implémentations __str__ pour les modèles. Ils ne sont pas vraiment nécessaires car la classe de base fait quelque chose d'assez bon, à moins que vous ne vouliez la rendre plus attrayante
2) Essayez de renvoyer plus d'un str(int) là-dedans, donc il ne peut pas être mal interprété:
File "/usr/local/lib/python3.7/dist-packages/rest_framework/relations.py", line 221, in display_value
return str(instance)
Je ne trouve cette erreur spécifique nulle part dans django ou drf, donc sans le déboguer directement, je n'ai plus de suggestions.
your Subscriber.__str__ renvoie également un int. changement:
def __str__(self):
return str(self.subscriberID)
à
def __str__(self):
return self.subscriberID
pouvez-vous afficher la vue correspondante?
Ajout de quelques extraits de views.py, urls.py, admin.py, serializers.py
return str (self.transferId) et transtyper les entiers en chaînes.
Pourquoi définir des méthodes str comme celle-ci sur les objets? Vous fiez-vous à ce comportement d'une manière ou d'une autre et que se passe-t-il avec un nouvel objet qui a "Aucun" pour l'ID?
@AndrewBacker J'ai parcouru et commenté la def __str __ (self): sur les modèles d'abonnés et de bureau, et j'avais toujours le même problème ... puis je suis allé et j'ai fait cela à TOUS mes modèles, et maintenant tout fonctionne - merci !
@AndrewBacker à ajouter ... J'ai eu tous mes modèles retournant INT sous la méthode str , mais avec vos conseils, j'ai pu modifier chacun pour renvoyer une chaîne (c'est-à-dire nom d'utilisateur au lieu d'ID utilisateur #) et maintenant tout s'affiche correctement dans l'API. Merci encore
Super, heureux qui a fonctionné! À mon avis, str () ne devrait vraiment être appelé que sur un modèle soit volontairement, soit en sortie de débogage. Cela fonctionne bien dans l'administrateur en tant que rapide et sale, mais vous voulez probablement avoir une fonction personnalisée dans votre administrateur qui donne des informations meilleures / plus claires. En tant que base, mon str est juste
f"ModelName({self.name})"ou tout aussi simple, mais la valeur par défaut fonctionne également.Si vous répondez à votre question, veuillez cocher l'une des réponses ci-dessous comme acceptée.