bsky
bsky

Reputation: 20222

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?

Upvotes: 0

Views: 7654

Answers (2)

Sebastian Wozny
Sebastian Wozny

Reputation: 17506

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)

Upvotes: 3

norbertoonline
norbertoonline

Reputation: 351

You have to call your model in the following way inside your view

from myapp.models import Question

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

for more information read the official documentation about views... https://docs.djangoproject.com/en/1.10/topics/http/views/

Upvotes: 0

Related Questions