octavian octavian - 25 days ago 15
Python Question

NameError: global name 'Model' is not defined

I have a simple Django app where I want to define two tables in the database:

user
and
question
.

I have the following
models.py
:

from django.db import models

class User(models.Model):
name = models.CharField(max_length=100)

@classmethod
def create(cls, name):
user = cls(name=name)
return user


class Question(models.Model):
content = models.CharField(max_length=300)
answer = models.CharField(max_length=200)

@classmethod
def create(cls, content, answer):
question = cls(content=content, answer=answer)
return user


In
/questions
, which is defined in
views.py
, I would like to display all objects of type
question
:

from django.views.generic.base import TemplateView
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.db import models


def questions(request):
questions = Model.objects.raw('SELECT * FROM questions')
return render_to_response('questions.html', questions)


However, I am getting:

NameError: global name 'Model' is not defined


Why is the
Model
object visible in
models.py
but not in
views.py
?

Also, is the way in which I query the database correct?

Answer

Answer to the question

Model is not visible in models.py - it's accessed as models.Model.

You're importing models but trying to use Model instead of models.Model.

Try this:

def questions(request):
    questions = models.Model.objects.raw('SELECT * FROM questions')
    return render_to_response('questions.html', questions)

Alternatively you can import Model directly:

from django.db.models import Model

Answer to the problem

I think this is a case of the XY problem.

What you really want to do is access all instances of the Question model. If you want to use function based views for some reason, you can import the Question model and use it directly with .all():

Function based views

question/views.py

from myapp.models import Question

def questions(request):
    questions = Question.objects.all()
    return render_to_response('questions.html', questions)

Class based views

The better option however, is to use a class based generic view. An example from the documentation:

questions/views.py

from django.views.generic import ListView
from questions.models import Question

class QuestionList(ListView):
    model = Question

urls.py

from django.conf.urls import url
from questions.views import QuestionList

urlpatterns = [
    url(r'^questions/$', QuestionList.as_view()),
]

Class based views offer much bigger expressiveness than funciton based viwes. They also eliminate the need for a lot of code duplication since commonly changed parts of a view can be overridden individually (e.g. get_context_data)

Comments