'how can i filter my model to get user answer for a current question
I have two models the Answer model and the Question model. when user post the question i want another user to be able to post an answer in the current question similar to stack overflow, i know using this method: MyModel.objects.all() will returns all the answers from all question to a each question, that's is not what i want. How can i do this in Django please ?
my model
class Question(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=100, blank=False, null=False)
body = RichTextField(blank=False, null=False)
category = models.CharField(max_length=50, blank=False, null=False)
def __str__(self):
return str(self.user)
class Answer(models.Model):
user = models.ForeignKey(User, null=False, blank=False, on_delete=models.CASCADE)
answer = RichTextField(blank=False, null=False)
post = models.ForeignKey(Question, null=False, blank=False, on_delete=models.CASCADE)
def __str__(self):
return str(self.user)
i want to pass user's Answer into this viewQuestion view
my view
def viewQuestion(request, pk):
question = Question.objects.get(id=pk)
context = {'question':question}
return render(request, 'viewQuestion.html', context)
class My_Answer(LoginRequiredMixin, CreateView):
model = Answer
fields = ['answer']
template_name = 'answer.html'
success_url = reverse_lazy('index')
def form_valid(self, form):
form.instance.user = self.request.user
return super (My_Answer, self).form_valid(form)
my urls
path('answer/', views.My_Answer.as_view(), name='answer'),
my url in viewQustion template
<div class="container">
<div class="row justify-content-center">
<a href="{% url 'answer' %}" class="btn btn-primary">Post Your
Answer</a>
</div>
</div>
my question form
<div class="container">
<div class="row justify-content-center">
<div class="col-md-5">
{% load crispy_forms_tags %}
<form method="POST" action="" enctype="multipart/form-data">
{% csrf_token %}
{{ form | crispy }}
<input type="submit" value="submit" class="btn btn-warning">
</div>
</div>
</form>
</div>
my question view
class My_Question(LoginRequiredMixin, CreateView):
model = Question
fields = ['title', 'body', 'category']
template_name = 'question.html'
success_url = reverse_lazy('index')
def form_valid(self, form):
form.instance.user = self.request.user
return super (My_Question, self).form_valid(form)
my answer form
<div class="container">
<div class="row justify-content-center">
<div class="col-md-5">
{% load crispy_forms_tags %}
<form method="POST" action="" enctype="multipart/form-data">
{% csrf_token %}
{{ form | crispy }}
<br>
<input type="submit" value="submit" class="btn btn-warning">
</div>
</div>
</form>
</div>
my question datail page
<div class="container">
<div class="row justify-content-center">
<h1>{{question.title}}</h1>
<hr>
</div>
<br>
<h3 style="font-family: arial;">{{question.body|safe}}</h3>
<hr>
<br>
<h5>{{question.user.username.upper}}</h5>
</div>
<!--Post Answer-->
<div class="container">
<div class="row justify-content-center">
<a href="{% url 'answer' %}" class="btn btn-primary">Post Your Answer</a>
</div>
</div>
<br>
<br>
<!--answers-->
<div class="container">
{% for answer in answers reversed %}
<div class="row justify-content-center">
<p>{{answer.user}}</p>
<p>{{answer.answer|safe}}</p>
</div>
{% endfor %}
</div>
Solution 1:[1]
Provide you Answer form on viewQuestion function like this it's good to follow this step for getting answers related to question.
def viewQuestion(request, pk):
question = Question.objects.get(id=pk)
form = MyForm()
if request.method == "POST":
form = MyForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.post = question
instance.save()
return redirect('my_success_url')
context = {
'question':question,
'answers': Answer.objects.filter(post=question),
'form':form
}
return render(request, 'viewQuestion.html', context)
instead of using Answer.objects.filter() you can use question.answers
Solution 2:[2]
First, you need to add the related_name attribute into the post attribute in the Answer model.
class Answer(models.Model):
...
post = models.ForeignKey(Question, null=False, blank=False, on_delete=models.CASCADE, related_name = "answers")
Then you can get answers from question like question.answers.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | David Lu |
