Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does UpdateView need to have model/queryset/get_queryset defined when using form_class as opposed to CreateView?

Works like a charm:

MyCreateView(CreateView):
    template_name = "my_template_name"
    form_class = MyModelForm
    success_url = "/success/"

But the following doesn't:

MyUpdateView(UpdateView):
    template_name = "my_template_name"
    form_class = MyModelForm
    success_url = "/success/"

I get this error:

MyUpdateView is missing a queryset. Define MyUpdateView.model, MyUpdateView.queryset, or override MyUpdateView.get_queryset().

Why does an UpdateView need model, queryset or get_queryset defined to not cause an error while CreateView doesn't? Shouldn't it be able to automatically derive it from the Model used in the ModelForm?

like image 854
Bentley4 Avatar asked Jul 12 '13 10:07

Bentley4


2 Answers

Currently (django 1.5.1 official release) UpdateView is calling self.get_object() to be able to provide instance object to Form.

From https://github.com/django/django/blob/1.5c2/django/views/generic/edit.py#L217:

def get(self, request, *args, **kwargs):
    self.object = self.get_object()
    return super(BaseUpdateView, self).get(request, *args, **kwargs)

def post(self, request, *args, **kwargs):
    self.object = self.get_object()
    return super(BaseUpdateView, self).post(request, *args, **kwargs)

And self.get_object method needs one of this properties declared: model, queryset or get_queryset

Whereas CreateView don't call self.get_object().

From https://github.com/django/django/blob/1.5c2/django/views/generic/edit.py#L194:

def get(self, request, *args, **kwargs):
    self.object = None
    return super(BaseCreateView, self).get(request, *args, **kwargs)

def post(self, request, *args, **kwargs):
    self.object = None
    return super(BaseCreateView, self).post(request, *args, **kwargs)
like image 67
stalk Avatar answered Sep 22 '22 01:09

stalk


You might have a problem in your urls.py file.

What I think you wrote in it is:

url(r'foldername/(?P[0-9]+)/$', views.UpdateView.as_view(), name='update'),

but you have to change UpdateView to MyUpdateView, like this: url(r'foldername/(?P[0-9]+)/$', views.MyUpdateView.as_view(), name='update'),

like image 30
Aviral Tiwari Avatar answered Sep 21 '22 01:09

Aviral Tiwari