how to display the data from the database in a template - python

i have following model:
class comment(models.Model):
userid=models.CharField(max_length=140)
apparelid=models.IntegerField(blank=True)
desc=models.TextField(blank=True)
def __unicode__(self):
return self.userid
form :
class commentForm(ModelForm):
class Meta:
model=comment
exclude=('userid','apparelid',)
and view as follows:
def comment(request,title_id):
if request.method=='POST':
form=commentForm(request.POST)
if form.is_valid():
new=form.save(commit=False)
new.userid=request.user.username
new.apparelid=title_id
new.save()
return HttpResponseRedirect('/')
else:
form=commentForm()
template=loader.get_template('apple3/comment.html')
context=RequestContext(request,{
'form':form,
}
)
return HttpResponse(template.render(context))
whenever i open my page containg above form it show an error as follows:
Exception Type: AttributeError
Exception Value: 'function' object has no attribute 'objects'

You probably import comment model from inside your view and then use comment again as view name. That's why the error gets thrown.
Please use different name for your view and model if you use them in the same module.

Problem at hand seems to be solved by #mariodev. Additionaly, I'd recommend two following steps as a mean of avoiding similar problems in future:
Read PEP8, the Style Guide for Python Code thoroughly
Use only packages and modules import.
Following those two links will make your code more pythonic and less error-prone.

The name of the model class and the view function is same which is resulting in the error:
Exception Value: 'function' object has no attribute 'objects'
You may use a different naming conventions for your classes and functions. As per PEP8, first letter of the class name should be capital/uppercase and the function's name should be lowercase.
So in your case, if you have to keep the names exactly same, you may rename your Model Class to Comment and let your view function's name be comment and that should solve the problem.

Related

in Django project. When annotate in views, getting error that item is not defined

I know, that this subject has been mentioned few times, but I can't find a solution for my problem. So please accept my apologies for a repeat request.
I have a condition-based filter, that doesn't work for me.
here is my models.py file:
class Itemslist(models.Model):
safety_stock = models.DecimalField(blank=True, null=True, max_digits=19, decimal_places=0)
current_stock = models.DecimalField(max_digits=19, decimal_places=0)
def above_below_ss(self):
ab = Decimal(self.current_stock-self.safety_stock)
return round(ab,0)
def __str__(self):
return self.item_n
Sorry, have to correct indentation, as it all belongs to one model class.
and here is what I have in views.py file:
from .models import *
def toorder(request):
# toorder=Itemslist.objects.all
sorted=Itemslist.objects.annotate(dontshow=above_below_ss()).exclude(dontshow__gt=0)
context={ 'sorted': sorted }
return render(request, 'toorder.html', context)
So here is a problem:
when I'm using
toorder=Itemslist.objects.all
everything works, but when I'm trying this:
sorted=Itemslist.objects.annotate(dontshow=above_below_ss()).exclude(dontshow__gt=0)
it doesn't.
Interesting thing is that it used to work, but my code crashed without a copy, (during a back-up, which is funny enough),
And now it doesn't work.
I'm getting this message:
NameError at /toorder
name 'above_below_ss' is not defined
Request Method: GET
Request URL: http://localhost:8000/toorder
Django Version: 2.2.5
Exception Type: NameError
Exception Value:
name 'above_below_ss' is not defined
Exception Location: /Users/artursjermolickis/projects/osmiocenter/mysite/itemlist/views.py in toorder, line 220
Python Executable: /Users/artursjermolickis/projects/osmiocenter/venv/bin/python3
Python Version: 3.7.4
Python Path:
['/Users/artursjermolickis/projects/osmiocenter/mysite',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python37.zip',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/lib-dynload',
'/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf']
If you need more pieces of code from me, please, just tell me what you need.
Really hope that you can help me here.
Here are additional comments to my question.
It is needed to filter the outcome by the mathematical function.
as an example I have posted safety_stock, and the solution, that is provided does work for that.
But as you have already mentioned, I need sort database, by a bit more complex function, so it's better to do it in models.py instead of doing it in vews.py that I can use it later. so the code, that I want to replace safety_stock with is:
def safe_stock(self):
if self.safety_stock ==0:
ss= (self.sales6mavgs()+self.stdev())*(self.lead_time+self.bookingterms)
else:
ss=Decimal(self.safety_stock)
return Decimal(ss.quantize(Decimal('1'),rounding=ROUND_UP))
So from your suggestions, I did understand, that I have to implement ExpressionWrapper.
How to implement it with ExpressionWrapper
Question is now answered, please see details below.
I have Added a Manager to my models.py:
class ToOrderManager(models.Manager):
def get_queryset(self):
return super(ToOrderManager, self).get_queryset().annotate(
dontshow=Round(ExpressionWrapper((F('current_stock')-F('safety_stock')), output_field=DecimalField()),0)
).annotate( leadtime=ExpressionWrapper(F('lead_time'), output_field=DecimalField())
).exclude(dontshow__gte=0).exclude(leadtime=0)
This lines have been added to my main model:
objects = models.Manager()
toorderobjects = ToOrderManager()
and my views.py looks like this now:
def toorder(request):
sorted=Itemslist.toorderobjects.all()
context={ 'sorted': sorted }
return render(request, 'toorder.html', context)
However in my case, it looks like I will have to perform Raw queries in my case, due to complicated calculations.
Thank you very much for knowledge sharing!!!
I dont think this dontshow=above_below_ss() was workign because it's an instance method that means that you first fetched a single record and then called it record.above_below_ss().
You can instead write this method as a part of the annotation using func and expression wrapper:
models.py
from django.db.models import Func
class Round(Func):
function = 'ROUND'
arity = 2
views.py
from django.db.models import DecimalField, ExpressionWrapper, F
from .models import Round
sorted=Itemslist.objects.annotate(dontshow=Round(ExpressionWrapper(F('current_stock') - F('safety_stock'), output_field=DecimalField()))).exclude(dontshow__gt=0)
If you want to reuse this you can move the query to manager and name it. Then, instead of each time writing long query, you'll simply use Itemslist.objects.whatever_name_you_chose()

Django: Fields of DeclarativeFieldsMetaclass (without instance)

I try to discover the fields which a django form class has.
I only have a class, not an instance.
The form-class is of type DeclarativeFieldsMetaclass.
If I try this:
class FooForm(forms.Form):
spreadsheet = forms.FileField()
for field in FooForm:
print(field)
I get this exception:
TypeError: 'DeclarativeFieldsMetaclass' object is not iterable
I know that I could do FooForm() instead of FooForm, but in my real use case I only have a class.
You can access FooForm.base_fields.

How to change a foreignkey field back to null?

Pretty new to Django. I am trying to switch the ForeignKey field student_information.project back to a null value. As well my student_remove object doesn't seem to be defining properly as 'Remove' should be an object.
Error Code
AttributeError at /project_list/projects/1/
type object 'Student_Information' has no attribute 'student_remove'
Request Method: GET
Request URL: http://127.0.0.1:8000/project_list/projects/1/?Remove=sathya
Django Version: 1.10.5
Exception Type: AttributeError
Exception Value:
type object 'Student_Information' has no attribute 'student_remove'
Exception Location: /media/rms/Sathya's Dr/mysite/projects/views.py in post_detail, line 27
Python Executable: /usr/bin/python
Python Version: 2.7.12
My views.py
def post_detail(request, pk):
post = get_object_or_404(Project, pk=pk)
students = Student_Information.objects.filter(project=post)
if request.GET.get('Remove'):
Remove = request.GET.get('Remove')
obj = Student_Information.objects.get(RCSID=Remove)
#obj.project = None
return render(request, 'projects/post_detail.html', {'post': post, 'students': students})
obj = Student_Information.objects.get(RCSID=Remove)
is throwing an, should specify that RCSID is a foreignkey, it seems like it's trying to find a primary key of 'sathya' where it should just get a string. How do I make it match the string? As if RCSID is automatically RCSID_id.
invalid literal for int() with base 10: 'sathya'
The error message is pretty clear. Student_Information model doesn't have any field named student_remove.
Apart from that, there are so many things wrong with your code.
In Django, you don't update the Model class. You update an instance of Model class. Records are saved as instances of Model class. So line Student_Information.student_remove.project = "---------", needs to be fixed.
student_information.project can be set to null by simply calling student_information.project = None. But here student_information is an instance of Student_Information model.
filter returns a Queryset, not an instance.
You need to call save on the Model instance to update it in the database.
I would recommend you to go through official polls app tutorial.
I made it work by passing id instead of RCSID so that they matched. Easy fix.

Accessing form fields as properties in a django view

According to the Django tutorial, you should access form fields using cleaned_data dictionary. I'm wondering why I can't access the properties of the form directly? My form validates just fine, but when I try to access it, Django complains that the object does not have the attribute. I added some code below that I hope will help diagnose the problem.
Form:
class CustomForm(forms.Form):
description = forms.CharField(widget = forms.TextInput(attrs = {'placeholder' : 'enter some text'}), label = "My form")
View:
def process_form(request):
if request.method != 'POST':
raise Http404
myForm = CustomForm(request.POST)
if not myForm.is_valid():
c = RequestContext(request)
return render_to_response('home/index.html', {'form' : myForm }, c)
# debug
print 'Description: ' + myForm.description # this does NOT work
# print 'Description: ' + myForm.cleaned_data['description'] # this does work
I get the following error: 'CustomForm' object has no attribute 'description'. Did I miss something in the docs that says I can't do that?
If your form is validated then you can access myForm cleaned_data:
print myForm.cleaned_data.get('description')
If you want to see why you cannot access myForm.description then you can see the data dictionary of your myForm:
print myForm.__dict__
The way you define fields using django.forms is just a convenient, declarative syntax; it's not really representative of what the final Form class, or an instance of it, looks like in terms of attributes.
Forms have a metaclass (without getting too deep into it, a metaclass is to declaring a class using the class keyword as an __init__ method is to creating an instance of a class using parentheses -- a hook to customise the object being created, which in the case of a metaclass, is a class!) which picks off Fields from the form class at definition time and adds them to a base_fields dict. When you instantiate a form, its base_fields are deep-copied to a fields attribute on the instance.
One point of confusion might be that you use . to access fields for display in templates -- what's actually happening there is that Django's template engine first attempts to use dictionary-style [] access to resolve property lookups and the base form class defines a __getitem__ method to take advantage of this, looking up the appropriate field from the form instance's fields dict and wrapping it with a BoundField, a wrapper which knows how to use the field and data from the form for displaying the field.
You can access the fields of a Form instance from its fields attribute.
myForm.fields['description']
And some property like label can be accessed like this:
myForm.fields['description'].label
Not sure how to display the value corresponding. Anybody having idea?
here is my reference
https://docs.djangoproject.com/en/dev/ref/forms/api/#accessing-the-fields-from-the-form
You can access your field trought dict.
form.__dict__["fields"]["description"]

AttributeError when using django-datatrans and django-markitup together

I am trying to use django-datatrans to translate a MarkupField (from django-markitup) on a model. Both apps work correctly independently, but when I register datatrans to translate a MarkupField then I can't add objects in the admin anymore.
Relevant code:
from django.db import models
from markitup.fields import MarkupField
from datatrans.utils import register
class Work(models.Model):
title = models.CharField(max_length=500)
content = MarkupField(help_text=MARKDOWN_HELP)
class WorkTranslation(object):
fields = ('title', 'content')
register(Work, WorkTranslation)
When I try to add a new Work-object in the admin I get the following error:
'unicode' object has no attribute 'raw'
The error happens here, in the markitup-module (in the line rendered = render_func(value.raw):
.../lib/python2.7/site-packages/markitup/fields.py in pre_save
def pre_save(self, model_instance, add):
value = super(MarkupField, self).pre_save(model_instance, add)
rendered = render_func(value.raw)
setattr(model_instance, _rendered_field_name(self.attname), rendered)
return value.raw
Local vars when failing:
add: False
model_instance: <Work: This is the title>
value: u'This is the content.'
self: <markitup.fields.MarkupField: content>
I have tried to inspect the variable value when the Work class is not registered for translation. In that case (and then it does work correctly) it is not a unicode string but an instance of markitup.fields.Markup.
I have not been able to figure out why the type changes and I realize this question is pretty specific. But I hope someone has insights anyway..
Had the same issue with django-modeltranslation and django-markitup when testing it:
class ModelTests(TestCase):
def test_my_class(self):
self.assertRaises(IntegrityError, models.MyClass.objects.create)
It works for me with:
class ModelTests(TestCase):
def test_my_class(self):
with self.assertRaises(IntegrityError):
models.MyClass.objects.create(info='', info_de='')
Where my installed languages are en and de. My default language is en. info is my field with markitup and translation. (I'm testing here that a field is required on MyClass, therefore the IntegrityError.)
(Btw. this produces a slightly different error:
class ModelTests(TestCase):
def test_my_class(self):
self.assertRaises(IntegrityError, models.MyClass.objects.create(info=''))
Error:
AttributeError: 'NoneType' object has no attribute 'raw'
)
Maybe this helps someone.

Categories

Resources