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 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)
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/
Related
I want to display a list of items and also a form to add further items at the end of the list. Hence I was thinking of creating a view as something below:
I have come across a class called ListCreateAPIView but I don't want to use django rest framework.
Please let me know your suggestions if and how can I club two generic class based view and how the path in urls.py would look like.
Further how should we refer to the list and create form objects in 'listnadd_task.html'?
<views.py>
from django.views.generic import ListView, CreateView
from .models import Task
from .forms import CreateTask
class ListAndAddView(ListView, CreateView)
model = Task
form_class = CreateTask
context_object_name = 'listnadd_task'
...
Please explain me how to match the Answer of a particular Question in django.
Right Now I am facing the issue that whatever the user inputs in the form if it exits in Answer database it returns True, But what I want is that whatever the user inputs should be matched with the Answer of that particular Question and not any of the Answers present.
models.py
from django.db import models
from django.contrib.auth import get_user_model
from PIL import Image
User=get_user_model()
# Create your models here.
class Question(models.Model):
question_name=models.CharField(max_length=20,unique=True,default=' ')
question_image=models.ImageField(upload_to='levels/')
question_text=models.TextField(blank=True,max_length=100)
def __str__(self):
return str(self.question_name)
class Meta:
ordering= ["question_name"]
class Answer(models.Model):
question_relation=models.ForeignKey(Question,on_delete=models.CASCADE)
answer=models.CharField(max_length=100,unique=True)
def __str__(self):
return self.answer
forms.py
from django import forms
from .models import Answer,Question
from django.core.exceptions import ObjectDoesNotExist
from . import views
class CheckAnswer(forms.Form):
your_answer=forms.CharField(label='Answer')
def clean(self):
cleaned_data=super(CheckAnswer,self).clean()
response=cleaned_data.get("your_answer")
try:
p = Answer.objects.get(answer__iexact=response)
except Answer.DoesNotExist:
raise forms.ValidationError("Wrong Answer.")
views.py
from django.shortcuts import render,redirect,get_object_or_404
from django.views.generic import *
from . import models
from django import forms
from .forms import CheckAnswer
from django.contrib.auth.decorators import login_required
from .models import Question
from dashboard.models import UserLoggedIn
# Create your views here.
#login_required
def Arena1(request):
if request.method=='POST':
form = CheckAnswer(request.POST)
if form.is_valid():
return redirect('thanks')
else:
form=CheckAnswer()
args={'form':form}
return render(request,'levels/arena1.html',args)
I think the concept of pk will be used but I dont know how to implement it
Please update my code that solves this problem.
First of All, Matching the Question would Require you to Store of Provide the Question to the Function Somehow. What You can do it use a Global Variable or a Container in which you would set the value while rendering the Question and then Import it to forms.py and set the your_question = Question
forms.py
from django import forms
from .models import Answer,Question
from django.core.exceptions import ObjectDoesNotExist
from . import views
class CheckAnswer(forms.Form):
your_answer=forms.CharField(label='Answer')
def clean(self):
cleaned_data=super(CheckAnswer,self).clean()
response=cleaned_data.get("your_answer")
try:
p = Answer.objects.get(answer__iexact=response)
if(your_answer == p.answer and your_question == p.question_relation.question_text): #user inputs should be matched with the Answer of that particular Question
#Code To Run for Correct Answer Goes Here
else:
#The Answer is Wrong or Does not Match the Particular Question
raise forms.ValidationError("Wrong Answer.")
except Answer.DoesNotExist:
raise forms.ValidationError("Wrong Answer.")
This is my first time using Django and I am completely stuck at how to use ModelForms in my project. I have been able to follow the online tutorials this far but without ModelForms(to add data into a Postgresql database), I can't proceed onward. I am trying to simply make a form page that lets the users add a few inputs (2 datefields and 1 textfield) and by submitting that form, the data will be added to the database.
The error I have been getting is:
AttributeError: 'Hyuga_Requests' object has no attribute 'name' [where Hyuga_Request is a class set in the models.py]
models.py
from __future__ import unicode_literals
from django.db import models
from django.forms import ModelForm
class Hyuga_Requests(models.Model):
name = models.CharField(max_length=50)
s_date = models.DateField(auto_now=True)
e_date = models.DateField(auto_now=True)
reason = models.TextField(max_length=500)
def __unicode__(self):
return self.name
views.py
from django.shortcuts import render
from django import forms
from .forms import Hyuga_RequestForm
def create_req(request):
form = Hyuga_RequestForm()
context = {"form":form,}
return render(request,"request_form/requestform.html", context)
forms.py
from django import forms
from .models import Hyuga_Requests
from django.forms import ModelForm
class Hyuga_RequestForm(forms.ModelForm):
class Meta:
model = Hyuga_Requests()
fields = ['name','s_date','e_date','reason']
Please help this noobie...
Don't instantiate the model in the class Meta inside the Hyuga_RequestForm class.
model = Hyuga_Requests() should be model = Hyuga_Requests
model = Hyuga_Requests() -> model = Hyuga_Requests
The error come because you are calling the model on the form.
from django import forms
from .models import Hyuga_Requests
from django.forms import ModelForm
class Hyuga_RequestForm(forms.ModelForm):
class Meta:
model = Hyuga_Requests
fields = ['name','s_date','e_date','reason']
Note: i suggest to you use on the any class you define on python not use "_", you can check more about PEP8 and code styles here: https://www.python.org/dev/peps/pep-0008/
I am trying to save two int values into my postgreSQL database and am coming up show with the following traceback: 'Data' object has no attribute 'save'. I can't figure out what is wrong.
My Models...
from django.db import models
class Data(models.Model):
value = models.IntegerField()
curr_time = models.IntegerField()
My Views...
from django.shortcuts import render,redirect
from django.views.generic import View
from django.http import JsonResponse
from models import Data
class Data(View):
def get(self, request, date, val):
data = Data(value=int(val), curr_time=int(date))
data.save()
return JsonResponse({'status': 111})
I have looked up and down Stack Overflow and haven't found any answers. Anyone see anything glarringly wrong?
Your view class's name and model class's name are same. Change the view class's name to something else i.e: DataView
Yes, change the name of the view!
from models import Data
class Data(View): # oops, name clash
...
The class definition name stomped on the imported name Data.
So I've been Googling around and can't find a solution to my problem. I'm honestly quite puzzled, so thanks for taking a look.
mysite/mysite/urls.py:
...
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
...
mysite/upgradelists/admin.py:
from django.contrib import admin
from upgrademe.models import GPU, CPU
class CPUAdmin(admin.TabularInline):
model = CPU
admin.site.register(CPU, CPUAdmin)
returned error:
AttributeError at /admin/
'CPUAdmin' object has no attribute 'urls'
However, if I change admin.py to:
class CPUAdmin(admin.ModelAdmin):
model = CPU
Then all is well. (although, irrelevant note: I believe the 'model = CPU' portion is redundant?)
Any help/insight into this would be greatly appreciated. Google has left me stumped, and searches over StackOverflow have turned up nothing that I can see is related.
I had the same problem, Google led me to this thread and it didn't help. I solved it while I was about to post my question.
I don't even know if it's the same problem you had, but here it is:
class UserAnswerInline(admin.TabularInline):
model = UserAnswer
class UserQuestionAdmin(admin.ModelAdmin):
inlines = [UserAnswerInline]
admin.site.register(UserQuestion, UserAnswerInline)
The correct code:
class UserAnswerInline(admin.TabularInline):
model = UserAnswer
class UserQuestionAdmin(admin.ModelAdmin):
inlines = [UserAnswerInline]
admin.site.register(UserQuestion, UserQuestionAdmin)
Spot the difference? Yup, wrong class name. Took me 5 hours before I decided to create a new question here, then figured it out while explaining the problem.
I have the same problem like this.
You can try this to fix this problem:
class CPUInline(admin.TabularInline):
model = CPU
class CPUAdmin(admin.ModelAdmin):
inlines = [CPUInline]
admin.site.register(CPU, CPUAdmin)
You can't register a tabular admin class directly with the admin site. TabularAdmin is a subclass of InlineAdmin, and as such is only for use in the inlines attribute of a full ModelAdmin.
This error happens to be coming from the part you expect least.
You can’t register InlineModelAdmin or it’s subclasses in the admin site. You can only use them in attributes of ModelAdmin classes.
This is the the most common cause of such error and it’s quite difficult to spot
The other answers are all correct in their own ways. Essentially, the offending line is admin.site.register(CPU, CPUAdmin).
Because this Model is included inline in another Model (which I'm assuming is GPU because it's the only other Model you are importing), you shouldn't register it but only the Model in which it will be inline-ed. So, removing the register line from admin.py will fix the object has no attribute 'urls'.
An inline can only be used in a modelAdmin that is why you get that error. As per my understanding on your code you need to write your code as.
class CPUInline(admin.TabularInline):
model = CPU
#admin.register(CPU)
class CPUAdmin(admin.ModelAdmin):
inlines = [CPUInline]
models.py
from django.db import models
class Teacher(models.Model):
name = models.CharField('First name',max_length=100)
students = models.ForeignKey('Student',on_delete=models.SET_NULL, null=True)
class Student(models.Model):
name = models.CharField('First name',max_length=100)
admin.py
from django.contrib import admin
from .models import Teacher, Student
from .models import Teacher as Teach
class TeacherInline(admin.TabularInline):
model = Teacher
class StudentAdmin(admin.ModelAdmin):
list_display = ('id','name')
inlines = [TeacherInline]
admin.site.register(Student,StudentAdmin)
admin.site.register(Teach)
But this does not show list_display and other options. For doing that, use flowing code:
admin.py
from django.contrib import admin
from .models import Teacher, Student
from .models import Teacher as Teach
class TeacherInline(admin.TabularInline):
model = Teacher
class StudentAdmin(admin.ModelAdmin):
list_display = ('id','name')
inlines = [TeacherInline]
class TeachAdmin(admin.ModelAdmin):
list_display = ('id','name')
admin.site.register(Student,StudentAdmin)
admin.site.register(Teach,TeachAdmin)