Home > Enterprise >  ValueError: Field 'id' expected a number but got '<built-in function id>';
ValueError: Field 'id' expected a number but got '<built-in function id>';

Time:04-11

When a User successfully makes a POST request to edit their own question, they are redirected to a detail page for the same question. When a subsequent GET request is sent to the PostedQuestionPage view after editing a question, the following ValueError is raised when trying retrieve an instance with get_object_or_404():

  • ValueError: Field 'id' expected a number but got '<built-in function id>'

Why is PostedQuestionPage being passed '<built-in function id>' and not a value that is suppose to represent a question instance id?

> c:\..\posts\views.py(137)get()
-> question = get_object_or_404(Question, id=question_id)
(Pdb) ll
134         def get(self, request, question_id):
135             import pdb; pdb.set_trace()
136             context = self.get_context_data()
137  ->         question = get_object_or_404(Question, id=question_id)
138             context['question'] = question
139             return self.render_to_response(context)
(Pdb) question_id
'<built-in function id>'
(Pdb) n
ValueError: Field 'id' expected a number but got '<built-in function id>'.
> c:\..\posts\views.py(137)get()
-> question = get_object_or_404(Question, id=question_id)
(Pdb) n
--Return--
> c:\..\posts\views.py(137)get()->None
-> question = get_object_or_404(Question, id=question_id)
class TestPostEditQuestionPage(TestCase):
    '''Verify that a message is displayed to the user in the event
    that some aspect of the previous posted question was edited.'''

    @classmethod
    def setUpTestData(cls):
        cls.user = get_user_model().objects.create_user(
            username="OneAndOnly",
            password="passcoderule"
        )
        profile = Profile.objects.create(user=cls.user)
        tag = Tag.objects.create(name="TagZ")
        question = Question.objects.create(
            title="This is Question Infinity",
            body="The is the content body for This is Question Infinity",
            profile=profile
        )
        question.tags.add(tag)

        cls.data = {
            "title": "This is Question Zero",
            "body": "The is the content body for This is Question Infinity",
            "tags_0": "TagN", "tags_1": "TagZ"
        }

    def test_posted_question_content_changed(self):
        self.client.force_login(self.user)
        response = self.client.post(
            reverse("posts:edit", kwargs={"question_id": 1}),
            data=self.data
        )
        self.assertRedirects(
            response, reverse("posts:question", kwargs={"question_id": 1}), 
            status_code=303
        )



class TestGetEditQuestionPage(TestCase):

    @classmethod
    def setUpTestData(cls):
        cls.user = get_user_model().objects.create_user("The_User_000")
        profile = Profile.objects.create(user=cls.user)
        tag = Tag.objects.create(name="TagABC")
        question = Question.objects.create(
            title="What is the difference between A & B?",
            body="I'm trying to figure out this out. Can you help me?",
            profile=profile
        )
        question.tags.add(tag)


    def test_user_question_instance_populates_edit_form(self):
        self.client.force_login(self.user)
        response = self.client.get(
            reverse("posts:edit", kwargs={
                'question_id': 1
            })
        )
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, "posts/ask.html")
        self.assertContains(response, "Edit your question")



from django.views.generic.base import TemplateView
from django.contrib import messages
from django.db import IntegrityError
from django.shortcuts import get_object_or_404
from django.urls import reverse

from authors.models import Profile
from .forms import SearchForm, QuestionForm, AnswerForm
from .models import Question, Tag, Answer

from django.http import HttpResponseRedirect
from authors.http_status import SeeOtherHTTPRedirect


class Page(TemplateView):

    def get_context_data(self, **kwargs):
        context = super().get_context_data()
        context['search_form'] = SearchForm()
        return context



class QuestionListingPage(Page):

    template_name = "posts/main.html"
    extra_context = {
        "title": "Top Questions",
        "query_buttons": ["Interesting", "Hot", "Week", "Month"]
    }

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['questions'] = Question.objects.all()
        return context

    def get(self, request):
        context = self.get_context_data()
        return self.render_to_response(context)


class AskQuestionPage(Page):

    template_name = "posts/ask.html"
    extra_context = {
        'title': "Ask a public question"
    }

    def attach_question_tags(self, tags):
        question_tags = []
        for name in tags:
            try:
                tag = Tag.objects.get(name=name)
            except Tag.DoesNotExist:
                tag = Tag.objects.create(name=name)
            finally:
                question_tags.append(tag)
        return question_tags

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['form'] = QuestionForm
        return context


    def post(self, request):
        context = self.get_context_data()
        form = context['form'](request.POST)
        if form.is_valid():
            tags = self.attach_question_tags(form.cleaned_data.pop("tags"))
            try:
                question = form.save(commit=False)
                question.profile = request.user.profile
                question.save()
            except IntegrityError:
                form.add_error(None, "This post is already posted")
                context['form'] = form
            else:
                question.tags.add(*tags)
                form.save_m2m()
                return SeeOtherHTTPRedirect(
                    reverse("posts:question", kwargs={"question_id": question.id})
                )
        return self.render_to_response(context)


class EditQuestionPage(AskQuestionPage):

    template_name = "posts/ask.html"
    extra_context = {
        'title': "Edit your question"
    }

    def get(self, request, question_id):
        question = get_object_or_404(Question, id=question_id)
        context = self.get_context_data()
        context['form'] = context['form'](instance=question)
        return self.render_to_response(
            context, headers={
                'Content-Type': "text/html"
            }
        )

    def post(self, request, question_id):
        question = get_object_or_404(Question, id=question_id)
        context = self.get_context_data()
        form = context['form'](request.POST, instance=question)
        if form.is_valid():
            if form.has_changed():
                messages.success(request, "Question updated!")
            x = form.cleaned_data.pop("tags")
            tags = self.attach_question_tags(x)
            question = form.save()
            question.tags.set(tags)
            return SeeOtherHTTPRedirect(reverse(
                "posts:question", kwargs={"question_id": id}
            ))
        return self.render_to_response(context)


class PostedQuestionPage(Page):

    template_name = "posts/question.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['answer_form'] = AnswerForm
        return context

    def get(self, request, question_id):
        context = self.get_context_data()
        question = get_object_or_404(Question, id=question_id)
        context['question'] = question
        return self.render_to_response(context)


    def post(self, request, question_id):
        question = get_object_or_404(Question, id=question_id)
        context = super.get_context_data()
        form = context['answer_form'](request.POST)
        if form.is_valid():
            form.cleaned_data.update({"profile": request.user.profile})
            answer = Answer.objects.create(
                **form.cleaned_data, question=question
            )
            return SeeOtherHTTPRedirect(
                reverse("posts:question", kwargs={
                    "question_id": answer.question.id
                })
            )

class EditPostedAnswerPage(PostedQuestionPage):

    def get(self, request, question_id, answer_id):
        context = super().get_context_data()
        question = get_object_or_404(Question, id=question_id)
        answer = get_object_or_404(Answer, id=answer_id)
        context.update({
            "answer_form": context['answer_form'](instance=answer),
            'question': question,
            'answer': answer
        })
        return self.render_to_response(context)

    def post(self, request, question_id, answer_id):
        context = super().get_context_data()
        question = get_object_or_404(Question, id=question_id)
        answer = get_object_or_404(Answer, id=answer_id)
        # import pdb; pdb.set_trace()
        if context['answer_form'](request.POST, instance=answer).is_valid():
            return SeeOtherHTTPRedirect(
                reverse("posts:question", kwargs={
                    'question_id': 1
                })
            )

CodePudding user response:

class EditQuestionPage(AskQuestionPage):
    ...

    def post(self, request, question_id):
        ...
        return SeeOtherHTTPRedirect(reverse(
            "posts:question", kwargs={"question_id": id}
        ))

This is the problem. You're passing the built-in function id as question_id.

  • Related