Sanjay
Sanjay

Reputation: 53

KeyError, Exception Value: 'object'

Projects picture1

I'm working on Django. I'm getting the error below. I didn't find the solution despite the much increased.Please refer the this link for trace back

Codes in views.py

class UpdateVote(LoginRequiredMixin,UpdateView):
    form_class = VoteForm
    queryset = Vote.objects.all()

    def get_object(self,queryset=None):
        vote = super().get_object(queryset)
        user = self.request.user
        if vote.user != user:
            raise PermissionDenied('can not change another user vote')
        return vote
    def get_success_url(self):
        movie_id = self.object.movie.id
        return reverse('core:movie_detail', kwargs={'pk':movie_id})
    def render_to_response(self, context, **response_kwargs):
        movie_id = context['object'].id
        movie_detail_url = reverse('core:movie_detail',kwargs={'pk':movie_id})
        return redirect(to=movie_detail_url)

class MovieDetail(DetailView):
    queryset = Movie.objects.all_with_prefetch_persons()
    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        if self.request.user.is_authenticated:
            vote = Vote.objects.get_vote_or_unsaved_blank_vote(movie=self.object,user=self.request.user)
            if vote.id:
                vote_url_form = reverse('core:UpdateVote',kwargs={'movie_id':vote.movie.id,'pk':vote.id})
            else:
                vote_url_form = (reverse('core:create_vote',kwargs={'movie_id':self.object.id}))
            vote_form = VoteForm(instance=vote)
            ctx['vote_form'] = vote_form
            ctx['vote_url_form'] = vote_url_form
        return ctx

Codes in form.py

I have used this form to link with UpdateView

from django import forms
from django.contrib.auth import get_user_model
from .models import Movie,Vote
class VoteForm(forms.ModelForm):
    user = forms.ModelChoiceField(widget=forms.HiddenInput,queryset=get_user_model().objects.all(),disabled=True)
    movie = forms.ModelChoiceField(widget=forms.HiddenInput,queryset = Movie.objects.all(),disabled=True)
    value = forms.ChoiceField(widget=forms.RadioSelect,choices=Vote.VALUE_CHOICE)
    class Meta:
        model = Vote
        fields = ('value','user','movie',)

urls.py

This is the url mapping for the view.

from django.contrib import admin
from django.urls import path
from .views import MovieList,MovieDetail,PersonDetail,CreateVote,UpdateVote
app_name = 'core'
urlpatterns = [
    path('movies/', MovieList.as_view(), name='movie_list'),
    path('movie/<int:pk>/', MovieDetail.as_view(), name='movie_details'),
    path('person/<int:pk>/', PersonDetail.as_view(), name='person_details'),
    path('movie/<int:movie_id>/vote/', CreateVote.as_view(), name='create_vote'),
    path('movie/<int:movie_id>/vote/<int:pk>', UpdateVote.as_view(), name='UpdateVote'),
]

HTML template

This is the template I used.

{% block sidebar %}
    <div>
    {% if vote_form %}
        <form action="{{vote_form_url}}" method="post" enctype="multipart/form-data">
            {% csrf_token %}
            {{ vote_form.as_p }}
            <button class="btn btn-primary" type="submit" >Vote</button>
        </form>
    {%  else %}
        <p>Login to vote for this movie</p>
    {% endif %} </div> {% endblock %}

Upvotes: 0

Views: 853

Answers (1)

Toan Quoc Ho
Toan Quoc Ho

Reputation: 3378

Your UpdateVote view is using VoteForm and the queryset on that view is from Vote model, so that the object field inside that view is the instance of Vote model, not Movie model.

This code movie_id = context['object'].id also not work because context might not included object of UpdateVote view, that caused the error KeyError, Exception Value: 'object'. You could get movie_id via kwargs field inside UpdateVote view because you've already defined movie_id in the path.

With this:

path('movie/<int:movie_id>/vote/<int:pk>', UpdateVote.as_view(), name='UpdateVote'),

Your view can get the values by using kwargs like so:

class UpdateVote(LoginRequiredMixin,UpdateView):
    form_class = VoteForm
    queryset = Vote.objects.all()

    def get_object(self,queryset=None):
        vote = super().get_object(queryset)
        user = self.request.user
        if vote.user != user:
            raise PermissionDenied('can not change another user vote')
        return vote

    def get_success_url(self):
        movie_id = self.kwargs.get('movie_id')
        return reverse('core:movie_detail', kwargs={'pk':movie_id})

    def render_to_response(self, context, **response_kwargs):
        movie_id = self.kwargs.get('movie_id')
        movie_detail_url = reverse('core:movie_detail',kwargs={'pk':movie_id})
        return redirect(to=movie_detail_url)

Upvotes: 1

Related Questions