Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Post request with DJango DetailView give error 'MyView' object has no attribute 'object'

I am trying to create an object with django DetailView. My code is like that.

class Detail(DetailView):
    model = MyModel
    template_name = 'mymodel_detail.html'

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

    def post(self, request, *args, **kwargs):
        form = DetailForm(request.POST, request.FILES)
        if form.is_valid():
            context['reply_form'] = DetailForm
            self.object = super(Detail, self).get_object()
            context['object'] = super(Detail, self).get_object()

            return self.render_to_response(request=request, template=self.get_template_names(), context=context)
        else:
            context = context = super(Detail, self).get_context_data(**kwargs)
            context['reply_form'] = form
            self.object = super(Detail, self).get_object()
            context['object'] = super(Detail, self).get_object()

            return self.render_to_response(request=request, template=self.get_template_names(), context=context)

But here I am getting error that

'Detail' object has no attribute 'object'

I tried to assign object in context instance and with self as well. But nothing works.

like image 249
n.imp Avatar asked Sep 10 '15 09:09

n.imp


3 Answers

What you are missing here is that you have to assign the object to the class or self before calling the get_context_data().

class Detail(DetailView):
    model = MyModel
    template_name = 'mymodel_detail.html'

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

    def post(self, request, *args, **kwargs):
        form = DetailForm(request.POST, request.FILES)
        if form.is_valid():
            # Write Your Logic here

            self.object = self.get_object()
            context = super(Detail, self).get_context_data(**kwargs)
            context['form'] = DetailForm
            return self.render_to_response(context=context)

        else:
            self.object = self.get_object()
            context = super(Detail, self).get_context_data(**kwargs)
            context['form'] = form
            return self.render_to_response( context=context)

and in render_to_response() Just pass context. No other arguments.

Hope it will work for you.

like image 130
Sarfraz Ahmad Avatar answered Oct 15 '22 21:10

Sarfraz Ahmad


This is how I implemented the code from Safrazs answer to make a reply option on my question model. I know this is an old question, but I hope that someone will find this useful.

class QuestionDetailView(generic.DetailView):
    model = Question
    template_name = 'forum/question.html'

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

        return context

    def post(self, request, *args, **kwargs):
        form = ReplyForm(request.POST)

        if form.is_valid():
            reply = form.save(commit=False)
            reply.creator = request.user
            reply.question = self.get_object()
            reply.save()
            self.object = self.get_object()
            context = context = super().get_context_data(**kwargs)
            context['form'] = ReplyForm

            return self.render_to_response(context=context)

        else:
            self.object = self.get_object()
            context = super().get_context_data(**kwargs)
            context['form'] = form

            return self.render_to_response(context=context)
like image 5
mischkez Avatar answered Oct 15 '22 19:10

mischkez


You are inheriting from the wrong generic view. You need to inherit from CreateView, like this:

class CreateModel(CreateView):
  model = MyModel
  template_name = 'mymodel_detail.html'
  form_class = DetailForm
  success_url = reverse('/thanks')

  def form_valid(self, form):
     # this method is called when the form
     # is successfully validated
     # if you need to do something with
     # the database object, this is the place
     # do not use it to redirect to a success page
     # use the success_url for that
     return super(CreateModel, self).form_valid(form)
like image 3
Burhan Khalid Avatar answered Oct 15 '22 20:10

Burhan Khalid