2012-08-01 5 views
0

J'essaie d'avoir une série de questions avec des réponses individuelles, auxquelles chaque utilisateur peut répondre. Pour réaliser ce type de fonction, j'ai construit les modèles suivants:Modèles Django et Inlines Admin

models.py:

class Question(models.Model): 
    question = models.TextField(null=False) 

class PossibleAnswer(models.Model): 
    question=models.ForeignKey(Question, related_name="possible_answer") 
    answer = models.CharField(max_length=200) 

class Answer(models.Model): 
    question = models.ForeignKey(Question) 
    user = models.ForeignKey(User) 
    real_answer = models.ForeignKey(PossibleAnswer, related_name="real_answer") 

Dans un premier temps admin-interface est assez, pour travailler avec ces questions. Il devrait être visible sur une « question par » base, d'où la « question » devrait montrer les réponses qu'il permet et les réponses des utilisateurs peut donner:

admin.py:

class AnswerInline(admin.TabularInline): 
    model = Answer 

class PossibleAnswerInline(admin.TabularInline): 
    model = PossibleAnswer 

class QuestionAdmin(admin.ModelAdmin): 
    inlines = [PossibleAnswerInline, AnswerInline] 

admin.site.register(Question, QuestionAdmin) 

Tout fonctionne très bien, jusqu'à ce que Je sauvegarde les réponses, ce qui produit une IntegrityError. Je crois que cela concerne les dépendances entre les objets?

deuxième point que je ne pouvais pas se déplacer avec: pour limiter les choix pour real_answer aux options réelles (qui sont liées à la question), je définis ce qui suit dans forms.py:

class AnswerForm(ModelForm): 
    class Meta: 
    model = Answer 

    def __init__(self, *args, **kwargs): 
    super(AnswerForm, self).__init__(*args, **kwargs) 
    choices = self.instance.question.possible_answer.all() 
    self.fields["real_answer"].choices = choices 

et l'utiliser dans admin.py comme suit:

class AnswerInline(admin.TabularInline): 
    model = Answer 
    form = AnswerForm 

quand je lance ce, self.instance.question.possible_answer.all() toujours soulève DoesNotExist

Tous les pointeurs sont très appréciés.

Best,

Andreas

Répondre

0

Lorsqu'un AnswerForm est initialisé, son attribut d'instance aura pas toujours un objet question qui s'y rapporte, donc chaque fois que vous référence self.instance.question de la forme, l'exception DoesNotExist sera levée s'il n'y a pas encore d'instance de question attachée à l'objet de réponse du formulaire.

Essayez ce code à la place dans votre formulaire méthode init:

choices = [] 
if self.instance.pk 
    questions = Question.objects.filter(answer=self.instance) 
    if questions.exist(): 
     choices = questions.get().possibleanswer_set.all() 
+0

bonne approche et cela fonctionne presque. Lorsque l'administrateur django affiche le formulaire, existe-t-il un moyen de limiter les options? dans les réponses déjà existantes, cela fonctionne, mais pas dans la nouvelle ligne en bas. –

+0

Il devrait y avoir, oui, s'il vous plaît se référer à la documentation admin de Django (et éventuellement des formulaires) pour cela. –

+0

Cela ne devrait-il pas aussi figurer dans le fichier AnswerForm? –

0

Je construis principalement sur @ la réponse de GonzaloDelgado, mais je ne pense pas son code est optimal. Il est préférable d'utiliser un bloc try...except.

from django.core.exceptions import ObjectDoesNotExist 
... 
def __init__(self, *args, **kwargs): 
    super(AnswerForm, self).__init__(*args, **kwargs) 

    if self.instance.pk: 
     try: 
      self.fields['real_answer'].queryset = self.question.possibleanswer_set.all() 
     except ObjectDoesNotExist: 
      pass 
+0

vous pouvez toujours modifier ma réponse :-) –

+0

Pas pour quelque chose comme ça. L'édition serait (et devrait être) rejetée pour être un «changement radical: cette édition change trop dans le message original, la signification ou l'intention originale du message serait perdue. –

+0

Désolé, je n'aurais pas pensé refactoriser mon code (le rendant "optimal") perdrait le sens ou l'intention de ma réponse. –