47

I am trying to use class based views, and get a strange error. The way I'm using the view seems to be the normal way:

ingredients/models.py:

from django.db import models
from django.utils import timezone


class Ingredient(models.Model):
    name        = models.CharField(max_length=255)
    description = models.TextField()

    def get_prices():
        purchases   = self.purchase_set.all()
        prices      = [purchase.price for purchase in purchases]

ingredients/views.py:

from django.shortcuts           import render, render_to_response, redirect
from django.http                import HttpResponse, HttpResponseRedirect
from django.views.generic.edit  import CreateView
from .models                    import Ingredient, Purchase

def IngredientCreateView(CreateView):
    model = Ingredient
    fields = ['all']

ingredients/urls.py:

from django.conf.urls import patterns, include, url

from ingredients.views import IngredientCreateView

urlpatterns = patterns('',            
    url(r'^new_ingredient$',          IngredientCreateView.as_view(),             name='new-ingredient'),
)

I get

AttributeError at /ingredients/new_ingredient
'function' object has no attribute 'as_view'

I am on django 1.8.5. Why won't this view work? Thank you

codyc4321
  • 9,014
  • 22
  • 92
  • 165
  • In my case I was giving same name to `viewset` and `model`. Giving them different name solved my problem – Zohab Ali Nov 08 '18 at 13:09

6 Answers6

60

In my case, the problem was that I tried to use a @decorator on the class-based view as if it was a function-based view, instead of @decorating the class correctly.

EDIT: From the linked page, here is a way to apply @login_required to a class-based view:

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator

@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
krubo
  • 5,969
  • 4
  • 37
  • 46
  • Thank you I actually made the mistake of @csrf_exept decorator and hence it was failing – Aman Madan Sep 20 '20 at 19:43
  • can i ask you please what is name='dispatch' ? what do you mean – Kok Hyvv Apr 12 '21 at 12:31
  • @KokHyvv When you decorate the class, you're actually decorating a function within the class, in this case the 'dispatch' function which runs the view. Since the dispatch function is inherited, its name only appears here in the decorator. – krubo Apr 12 '21 at 22:01
  • aha okay i understand you thanks for explain – Kok Hyvv Apr 13 '21 at 01:02
59

IngredientCreateView should be a class. So your views.py replace:

def IngredientCreateView(CreateView):

with:

class IngredientCreateView(CreateView):
Anush Devendra
  • 5,285
  • 1
  • 32
  • 24
10

IngredientCreateView is a function, not a class.

The following line

def IngredientCreateView(CreateView):

should be replace with

class IngredientCreateView(CreateView):
falsetru
  • 357,413
  • 63
  • 732
  • 636
4
def Some_def_View(CreateView):

#should be replaced with

class SomeClassView(CreateView)
2

In addition to what is already said here, Check the file name and class name if it is same then you might have to import the class properly.

File name /api/A.py

class A:
//some methods

In your main class

//App main class
from api.A import A
Shirish Singh
  • 797
  • 7
  • 17
2

I faced the same problem but this solution worked for me..

in views.py file in viewclass you can use viewsets instead of CreateView

            from rest_framework import viewsets
            class YourClassView(viewsets.ModelViewSet):

in urls.py file you can use this routing pattern

          from django.conf.urls import url
          from rest_framework import routers

          router = routers.DefaultRouter()
          router.register('books',YourClassView)

          urlpatterns = [
               path('', include(router.urls)),
               path('admin/', admin.site.urls)
            ]
Sureja_Hit
  • 21
  • 2