2017-12-20 5 views
0

Ich habe folgende Modelle definiert:Erstellen django Form für verwandte Modelle

class Question(models.Model): 
    date_added = models.DateTimeField(auto_now_add=True) 
    question = models.CharField(max_length=200) 
    number_of_answers = models.IntegerField(default=0) 

class Answer(models.Model): 
    question = models.ForeignKey(Question) 
    answer = models.CharField(max_length=200) 
    votes = models.IntegerField(default=0) 

Ich möchte der Benutzer eine Frage zu schaffen, um der Lage sein, zusammen mit seinen entsprechenden Antworten.

Grundsätzlich möchte ich ein Formular erstellen, das den Benutzer auffordert, eine Frage und die Anzahl der Antworten für die Frage einzugeben. Basierend auf der angegebenen Anzahl von Antworten möchte ich dann so viele Textfelder für jede Antwort erstellen. Ich möchte in der Lage sein, jede Antwort mit der entsprechenden Frage in der Datenbank zu verbinden.

Was ist der beste Weg, dies in Python Django zu tun? Ich habe Bilder davon geliefert, wie dies visuell aussehen würde. Getting question and number of answers, getting answers based on question and number of answers specified

Antwort

0

ich dieses Problem durch die Verwendung modelForms für die Erstellung von Fragen angehen würde, und dann auf eine Seite umgeleitet, wo Sie die Anzahl der Fragen hinzufügen können, den Sie bei der Frage erstellt. Diese add_answers Seite verwendet keine Django-Formulare, wir können einfach ein einfaches HTML-Formular verwenden und dann die Formulardaten in der Ansicht abrufen. Hier sind die Ansichten:

views.py:

from django.shortcuts import render, redirect 
from .forms import QuestionForm 
from .models import Question, Answer 

# Create your views here. 

def add_question(request): 
    form = QuestionForm(request.POST or None) 
    if request.method == "POST": 
     if form.is_valid(): 
      question = form.cleaned_data.get('question') 
      number_of_answers = form.cleaned_data.get('number_of_answers') 
      create_question = Question.objects.create(question=question, number_of_answers=number_of_answers) 
      create_question.save() 
      return redirect('home:add-answers', id=create_question.id) 
    return render(request, 'home/add_question.html', {'form': form}) 


def add_answers(request, id): 
    question = Question.objects.get(id=id) 
    if request.method == "POST": 
     for i in request.POST.getlist('answers'): 
      _ = Answer.objects.create(answer=i, question=id) 
      _.save() 

    num_answers = question.number_of_answers 
    context = {"num_answers":range(num_answers), 'question':question} 
    return render(request, 'home/add_answers.html', context) 

verwendet Vordrucke:

forms.py:

from django import forms 
from .models import Question, Answer 

class QuestionForm(forms.ModelForm): 

    class Meta: 
     model = Question 
     fields = ['question','number_of_answers'] 

Wir dieses Formular zugreifen können die Vorlage:

<form method="POST" action="."> 
    {{ form }} 
    {% csrf_token %} 
    <input type="submit">Submit</input> 
</form> 

Für add_answers wir Sie wie folgt vor:

<form method="POST" action="."> 
    {% for i in num_answers %} 
     <input type="text" name="answers"></input> 
     <br /> 
    {% endfor %} 
    {% csrf_token %} 
    <input type="submit">Submit</input> 
</form> 

Wo num_answers ist eine Kontextvariable, die range(number_of_answers) ist.

Edit: hier ist die urls.py file:

from django.conf.urls import url, include 
from . import views 

urlpatterns = [ 
    url(r'^add-answers/(?P<id>\d+)/$', views.add_answers, name="add-answers"), 
    url(r'^add-question/$', views.add_question, name="add-question"), 
] 
+0

Hallo, danke für Ihre Antwort. Ich habe Ihren Vorschlag ausprobiert und erhalte eine NoReverseMatch-Ausnahme, die besagt: "\t Reverse für 'add_answers' nicht gefunden. 'Add_answers' ist keine gültige Ansichtsfunktion oder kein Mustername." Weißt du vielleicht, warum ich diesen Fehler bekomme? – km786

+0

@ km786 Ich habe meine Antwort mit ** urls.py ** aktualisiert. Der Fehler könnte von 'return redirect ('home: add-answers', id = create_question.id) 'kommen, wenn Sie nicht den Namen' add-answer 'in urls.py gesetzt haben. Ich hoffe, dass hilft, lass es mich wissen, wenn du mehr Klarheit brauchst. Danke – briancaffey

+0

Hallo! Vielen Dank! Es funktioniert jetzt! – km786

0

Werfen Sie einen Blick von formsets .Und mit django-dynamic-forms kombinieren können Sie benutzerdefinierte eine Webseite hinzufügen Frage mit Antwort helfen.

Hier ist eine Demo von fügen Sie ein Team mit seinem Spieler.

models.py

class Player(models.Model): 
    name = models.CharField(max_length=50) 
    score = models.IntegerField() 
    age = models.IntegerField() 

    def __str__(self): 
     return self.name 


class Team(models.Model): 
    name = models.CharField(max_length=100) 
    players = models.ManyToManyField(Player) 

    def __str__(self): 
     return self.name 

forms.py

from django import forms 
from django.forms.formsets import formset_factory 
from .models import * 


class PlayerForm(forms.ModelForm): 
    class Meta: 
     model = Player 
     fields = '__all__' 


PlayerFormset = formset_factory(PlayerForm) 


class TeamForm(forms.Form): 
    name = forms.CharField() 
    players = PlayerFormset() 

views.py

from django.shortcuts import render 

from .forms import * 
from .models import * 


def post(request): 
    if request.method == 'POST': 
     form = TeamForm(request.POST) 

     player_instances = PlayerFormset(request.POST) 
     if form.is_valid(): 
      if player_instances.is_valid(): 
       team = Team(name=form.cleaned_data['name']) 
       team.save() 
       args = {'form': form} 
       for item in player_instances: 
        if item.is_valid(): 
         player = item.save() 
         team.players.add(player) 
        else: 
         print('-----------error occur') 
       team.save() 
       return render(request, 'app1.html', args) 

     args = {'form': form} 
     return render(request, 'app1.html', args) 
    else: 
     form = TeamForm() 
     args = {'form': form} 
     return render(request, 'app1.html', args) 

app1.html

<html> 
<head> 

    <title>gffdfdf</title> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> 

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
    <script src="/static/jquery.formset.js"></script> 
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> 

</head> 
<body> 

<div class="container"> 

    <form id="myForm" action="" method="post" class=""> 
     {% csrf_token %} 
     <h2> Team</h2> 
     {% for field in form %} 
      {{ field.errors }} 
      {{ field.label_tag }} : {{ field }} 
     {% endfor %} 
     {{ form.players.management_form }} 

     <h3> Product Instance(s)</h3> 
     <table id="table-product" class="table"> 
      <thead> 
      <tr> 
       <th>player name</th> 
       <th>highest score</th> 
       <th>age</th> 
      </tr> 

      </thead> 
      {% for player in form.players %} 
       <tbody class="player-instances"> 

       <tr> 
        <td>{{ player.name }}</td> 
        <td>{{ player.score }}</td> 
        <td>{{ player.age }}</td> 
       </tr> 

       </tbody> 
      {% endfor %} 
     </table> 
     <button type="submit" class="btn btn-primary">save</button> 

    </form> 
</div> 
<script> 
    $(function() { 
     $('#myForm tbody tr').formset(); 
    }) 
</script> 
</body> 
</html> 

Bildschirm wie: enter image description here

Verwandte Themen