Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Problème de clé étrangère (Django REST Framework)

+4 votes

Je rencontre un problème avec les clés étrangères dans les vues par défaut de Django REST Framework : elles ne sont jamais renseignées dans le formulaire de modification (PUT) alors que leur valeur est bien représentée dans le flux de données.

J'ai le serializer et le viewset suivants :

class AdressePersonnePhysiqueSerializer(serializers.ModelSerializer):
    class Meta:
        model = AdressePersonnePhysique


class AdressePersonnePhysiqueViewSet(viewsets.ModelViewSet):
    queryset = AdressePersonnePhysique.objects.all()
    model = AdressePersonnePhysique
    serializer_class = AdressePersonnePhysiqueSerializer

Rien d'exceptionnel comme vous pouvez le voir. Voici par exemple le JSON d'une donnée consultée :

{
    "id": 1,
    "liens": null,
    "libelle": null,
    "type_contact": "PE",
    "type_adresse": "S",
    "destinataire": "BAPTISTE PHILIPPE",
    "numero_appartement": "",
    "residence": "",
    "voie": "23 AVENUE DU FAISAN DORE",
    "lieu_dit": "",
    "code_postal": "17200",
    "ville": "ST SULPICE DE ROYAN",
    "pays": "FRANCE",
    "personne": 2
}

Le modèle AdressePersonnePhysique est, comme vous vous en doutez, relié à un autre modèle PersonnePhysique via une relation de type ForeignKey.

Dans cet exemple, la personne à l'identifiant n°2 est un certain BAPTISTE PHILIPPE, cependant lorsque l'on regarde le formulaire de modification de cette entité dans l'API REST, on remarque qu'il ne récupère pas cette valeur :

Formulaire PUT de l'API REST

En fait, l'affichage prend uniquement le premier élément de la liste des personnes par défaut, vu que le champ est non nul. Bref, c'est incohérent avec les données présentées mais ça n'altère pas le fonctionnement du PUT pour autant, si j'envoie une requête en JSON avec l'identifiant de la personne qui m'intéresse, la sauvegarde en prend bien compte, c'est clairement un problème d'affichage.

Je suis en dernière version de Django (1.7.2) et dernière version de Django REST Framework (3.0.2).

Voici le modèle associé à l'exemple

demandé 13-Jan-2015 par debnet (1,024 points)
edité 13-Jan-2015 par debnet

la dernière version de DRF est une 3.0.3 ; l'as tu essayée pour voir si ça ne corrigerait pas le pb ?.

on pourrait voir la tête du modèle (qd même) juste en éditant le message initial ?

sinon j'ai l'impression en lisant la doc que dans ton viewsets.ModelViewSet la ligne model sert à rien. Du coup peut-être un effet de bord ?
soit la ligne model = soit la ligne queryset = ; non ?

si c'est bien ça je te ferai une "vraie" réponse que tu pourras valider pour que le suivant ait aussi la solution

Regarde par hasard si ce n'est pas juste un problème d'affichage du navigateur (ca m'est déjà arrivé). Inspecte ton code et vérifie la balise option qui a l'attribut selected.

J'ai regardé dans le code HTML, aucun élément n'est sélectionné.

La ligne model dans le viewset est inutile mais DRF s'en fout.
Je suis en DRF 3.0.2 (voir screen) au fait, pas en 3.0.1. La 3.0.3 n'est pas encore sur les dépôts.
Je t'ajoute le modèle dans le message.

c'est con parce qu'elle est annoncée sortie http://www.django-rest-framework.org/topics/release-notes/#30x-series (sur pypi https://pypi.python.org/pypi/djangorestframework/3.0.3) , j'attends de voir le model mais j'étais plus sûr pour le coup du model indiqué "pour rien"

Je viens de forcer l'update en 3.0.3, toujours le même problème. Cependant je n'ai pas le soucis avec les HyperLinkedSerializer, le champ de la clé étrangère se met bien à jour.

tu pourrais pas reduire ton models.py à 2 models ? parce que là ... c'est pas possible de debugger en plus ya pas non plus Entity etc...
j'ai l'impression que le related_name poserait probleme.

Je viens d'essayer avec 2 modèles simples sans notre surcouche Entity, ça fait exactement la même chose, je me demande si c'est pas un problème de configuration de DRF...

Django REST Framework configuration

REST_FRAMEWORK = {
    'DEFAULT_MODEL_SERIALIZER_CLASS': 'rest_framework.serializers.HyperlinkedModelSerializer',
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.DjangoModelPermissions',
        # 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly',
        # 'rest_framework.permissions.IsAuthenticatedOrReadOnly',
        # 'rest_framework.permissions.IsAuthenticated',
        # 'rest_framework.permissions.IsAdminUser',
        # 'rest_framework.permissions.AllowAny',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        # 'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ),
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.BrowsableAPIRenderer',
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.XMLRenderer',
        # 'rest_framework.renderers.YAMLRenderer',
    ),
    'TEST_REQUEST_DEFAULT_FORMAT': 'json',
    'PAGINATE_BY': 10,
    'HYPERLINKED': True,  # Retourne les relations sous forme de liens ou de grappes d'objets
}

Ça sent le bug quand même. Tu fais rien de fou là.

Bug confirmé sur #django-fr et #restframework (@freenode).

On rédige un ticket dans la journée et je ferais le suivi ici.

Fait une réponse avec ce commentaire, comme ça il peut être accepté comme réponse.

ouais tu te auto valides ta reponse (si c'est possible :)

2 Réponses

+2 votes
 
Meilleure réponse

On a remonté le bug sur le GitHub de django-rest-framework.
https://github.com/tomchristie/django-rest-framework/issues/2416

J'ai mis un petit patch sur mon projet en attendant la milestone 3.0.4.

répondu 14-Jan-2015 par debnet (1,024 points)
0 votes

C'est bel et bien un bug.

répondu 14-Jan-2015 par anonyme
...