2017-09-27 2 views
0

J'ai une classe B qui contient une relation ForeignKey à la classe A. Lorsque j'instancie B je peux accéder au champ 'a' mais la relation inverse (qui devrait être créée automatiquement) génère une erreur. Concrètement, j'ai les définitions de classes suivantes:La relation descendante de clé étrangère Django ne fonctionne pas

from django.db.models import Model, CharField, DateField, ForeignKey 
from django.urls import reverse 

class Patient(Model): 

    GENDER = (
     ('M', 'Male'), 
     ('F', 'Female'), 
     ('U', 'Unknown'), 
    ) 

    last_name = CharField(max_length=128, null=False) 
    first_name = CharField(max_length=128, null=False, default='') 
    gender = CharField(max_length=1, choices=GENDER, null=False) 
    dob = DateField(null=False) 

    def get_absolute_url(self): 
     return reverse('patient_detail', args=[str(self.id)]) 

    def __str__(self): 
     return '{}, {} ({}, {})'.format(self.last_name, self.first_name, self.gender, self.dob) 


class AttributeSet(Model): 

    name = CharField(max_length=128, null=False) 
    description = CharField(max_length=256, blank=True, default='') 

    def get_absolute_url(self): 
     return reverse('attribute_set_detail', args=[str(self.id)]) 

    def __str__(self): 
     return self.name 


class AttributeSetInstance(Model): 

    patient = ForeignKey('Patient', null=False) # Automatic 'attribute_set_instance_set' backward relation? 
    attribute_set = ForeignKey('AttributeSet', null=False) 

    def get_absolute_url(self): 
     return reverse('attribute_set_instance_detail', args=[str(self.id)]) 

    def __str__(self): 
     return self.attribute_set.name 

Lorsque je tente de créer un nouveau AttributeSetInstance avec un patient et des arguments AttributeSet Je peux accéder aux patients et champs attribute_set, mais pas vice versa. Comme si:

Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 12:39:47) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
(InteractiveConsole) 
>>> from app.models import Patient, AttributeSet, AttributeSetInstance 
>>> p = Patient(last_name='Doe', first_name='John', gender='M', dob='1973-07-16') 
>>> p 
<Patient: Doe, John (M, 1973-07-16)> 
>>> a = AttributeSet(name='Set1') 
>>> a 
<AttributeSet: Set1> 
>>> i = AttributeSetInstance(patient=p, attribute_set=a) 
>>> i 
<AttributeSetInstance: Set1> 
>>> i.patient 
<Patient: Doe, John (M, 1973-07-16)> 
>>> i.attribute_set 
<AttributeSet: Set1> 
>>> p.attribute_set_instance_set 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
AttributeError: 'Patient' object has no attribute 'attribute_set_instance_set' 
>>> 

Ainsi, les travaux i.patient, mais p.attribute_set_instance_set ne fonctionne pas. Pour autant que je puisse comprendre, le gestionnaire par défaut qui est assigné aux relations ForeignKey ajoute un postfix '_set' à la relation arrière.

Une idée de ce que je fais mal? Ce serait d'une grande aide. Il est probablement quelque chose de stupide ...

Ralph

Répondre

1

Vous avez ajouté souligne où il ne devrait pas y avoir de. Le nom associé par défaut est le nom de la minuscule du modèle plus _set, donc pour AttributeSetInstance, il s'agit de attributesetinstance_set. Si vous souhaitez utiliser votre version de soulignement, vous pouvez la définir comme l'argument explicite related_name dans le champ ForeignKey.

+0

Merci! C'était ça! J'aurais pu deviner en fonction de la sortie de migration (elle montre les champs de manière écrasée sans underscores). – Ralph