how do I get the value or pk of a model in django?

Viewed 96

hey I'm a beginner in django and trying to make a question and answer project using class based views, im trying to make an answer form to write an answer for the question, the posting and all is already good.

but I don't know how to make it so that it posts the answer object to the correct question object in class based views, how do I do this? Please explain in a very simple way for a beginner, thank you!

oh sorry here's the code so far:

views.py:

class AskForm(SuccessMessageMixin , CreateView):
    template_name = 'forum/ask-question.html'
    model = Question
    form_class = QuestionForm
    success_message = 'Success!'
    
    
    def form_valid(self, form):
        form.instance.user = self.request.user
        form.save()
        return super(AskForm, self).form_valid(form)
    
class AnswerForm(SuccessMessageMixin, CreateView):
    template_name = 'forum/answer-question.html'
    model = Answer
    form_class = AnswerForm
    success_message = 'Success!'
    
    def form_valid(self, form):
        form.instance.user = self.request.user
        form.save()
        return super(AskForm, self).form_valid(form)

models.py:

# This is the question model
class Question(VoteModel, models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True)
    title = models.CharField(max_length=30)
    detail = models.TextField()
    tags = models.TextField(default='')
    add_time = models.DateTimeField(auto_now_add=True)
    
    def get_absolute_url(self):
        return f"/questions/"
    

    def __str__(self):
        return self.title


# This is the answer model

class Answer(VoteModel, models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    detail = models.TextField()
    add_time = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.detail

forms.py:

class QuestionForm(ModelForm):
    class Meta:
        model = Question
        fields = ['title', 'detail', 'tags']
        exclude = ('user', 'add_time')
        
class AnswerForm(ModelForm):
    class Meta:
        model = Answer
        fields = ['detail']
        exclude = ('user', 'add_time')

edit 2:

yep so again, trying to make a question and answer project in django and don't know how to tell the answer object which question object to attach to, I'm trying to make it so that I just click answer on the question detail page and it automatically knows that Im trying to send in the answer object to that specific question

traceback:

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/answer/

Django Version: 4.0.4
Python Version: 3.8.10
Installed Applications:
['django.contrib.humanize',
 'forum',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'crispy_forms',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'users',
 'vote']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "/home/titsnium/.local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/home/titsnium/.local/lib/python3.8/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/titsnium/.local/lib/python3.8/site-packages/django/views/generic/base.py", line 84, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/titsnium/.local/lib/python3.8/site-packages/django/views/generic/base.py", line 119, in dispatch
    return handler(request, *args, **kwargs)
  File "/home/titsnium/.local/lib/python3.8/site-packages/django/views/generic/edit.py", line 184, in post
    return super().post(request, *args, **kwargs)
  File "/home/titsnium/.local/lib/python3.8/site-packages/django/views/generic/edit.py", line 153, in post
    return self.form_valid(form)
  File "/home/titsnium/Documents/eduzec/forum/views.py", line 78, in form_valid
    _forum = get_object_or_404(Question, id=self.kwargs['pk'])

Exception Type: KeyError at /answer/
Exception Value: 'pk'

urls.py:

from django.urls import path
from . import views

urlpatterns = [
    path('questions/', views.QuestionsView.as_view(), name='questions'),
    path('ask/', views.AskForm.as_view(), name='ask'),
    path('answer/', views.AnswerForm.as_view(), name='answer'),
    path('detail/<pk>', views.QuestionDetailView.as_view(), name='detail'),
    path('save-text', views.WriteCommentAnswerView.as_view(), name='save-text'),
    path('save-vote', views.SaveVoteView.as_view(), name='save-vote'),
]

views.py:

from django.shortcuts import render, get_object_or_404
from django.http import JsonResponse, HttpResponseRedirect
from django.views import View
from django.views.generic.list import ListView
from django.views.generic import DetailView, CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Count
from requests import request
from .forms import QuestionForm, AnswerForm
from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse, reverse_lazy
from . import models
from .models import Question, Answer, Comment

from vote.models import UP, DOWN
from .utilities import cast_vote, save_text_help

class QuestionsView(ListView):
    model = Question
    template_name = 'forum/questions.html'
    context_object_name = "quests"
    paginate_by = 5

    def get_queryset(self):
        qs = super(QuestionsView, self).get_queryset()

        search = self.request.GET.get('q')
        if search:
            qs = qs.filter(title__icontains=search)

        qs = qs.order_by("-id")
        qs = qs.annotate(count_of_answers=Count('answer'))
        return qs

class QuestionDetailView(DetailView):
    model = Question
    template_name = 'forum/detail.html'
    context_object_name = 'quest'

    def get_context_data(self, **kwargs):
        context = super(QuestionDetailView, self).get_context_data(**kwargs)

        context['tags'] = self.object.tags.split(',')
        answers = Answer.objects.filter(question=self.object).order_by('-vote_score')    
        comments = []
        for answer in answers:
            comments.append(Comment.objects.filter(answer=answer))
        context['answers_comments'] = zip(answers, comments)
        
        return context

    def get_queryset(self):
        qs = super(QuestionDetailView, self).get_queryset()
        qs = qs.annotate(count_of_answers=Count('answer'))

        return qs
    

class AskForm(SuccessMessageMixin , CreateView):
    template_name = 'forum/ask-question.html'
    model = Question
    form_class = QuestionForm
    success_message = 'Success!'
    
    
    def form_valid(self, form):
        form.instance.user = self.request.user
        form.save()
        return super(AskForm, self).form_valid(form)
    
class AnswerForm(SuccessMessageMixin, CreateView):
    template_name = 'forum/answer-question.html'
    model = Answer
    form_class = AnswerForm
    success_message = 'Success!'
    
    def form_valid(self, request, form):
        _forum = get_object_or_404(Question, id=self.kwargs['pk'])
        form.instance.user = self.request.user
        form.instance.forum = _forum
        return super().form_valid(form)

class WriteCommentAnswerView(View):
    def post(self, request):
        text=request.POST['text']
        id=request.POST['id']
        text_type = request.POST['type']
        user=request.user

        if text_type == "comment":
            return render(request, 'forum/includes/single_comment.html', {'comment': save_text_help(text, id, text_type, user)})
        else:
            return render(request, 'forum/includes/single_answer.html', {'answer': save_text_help(text, id, text_type, user)})

class SaveVoteView(LoginRequiredMixin, View):
    def post(self, request):
        id = request.POST['id']
        user_id = request.user.id
        vote_to = request.POST['vote_to']
        vote_type = request.POST['vote_type']

        return JsonResponse({'bool': cast_vote(vote_type, vote_to, user_id, id)})
0 Answers
Related