Django: debug AttributeError: can't set attribute - django

NOTE: I finally found the bug, so the below text was valuable perhaps only to me. The short answer: I decided to create a model field out of an attribute I had earlier defined as a #property-method. The only place where I hadn't removed the #property-method was in the Orchid model.
After some tweaked and poking to my code, I suddenly get this error: AttributeError: can't set attribute. I haven't changed any of the code for Orchid, but I now get this error:
>>> orc = Orchid.objects.get(id=1)
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/Users/cole/PycharmProjects/Sites/virtualenvs/orchidislandcapital.com/lib/python2.7/site-packages/django/db/models/manager.py", line 151, in get
return self.get_queryset().get(*args, **kwargs)
File "/Users/cole/PycharmProjects/Sites/virtualenvs/orchidislandcapital.com/lib/python2.7/site-packages/django/db/models/query.py", line 301, in get
num = len(clone)
File "/Users/cole/PycharmProjects/Sites/virtualenvs/orchidislandcapital.com/lib/python2.7/site-packages/django/db/models/query.py", line 77, in __len__
self._fetch_all()
File "/Users/cole/PycharmProjects/Sites/virtualenvs/orchidislandcapital.com/lib/python2.7/site-packages/django/db/models/query.py", line 854, in _fetch_all
self._result_cache = list(self.iterator())
File "/Users/cole/PycharmProjects/Sites/virtualenvs/orchidislandcapital.com/lib/python2.7/site-packages/django/db/models/query.py", line 230, in iterator
obj = model(*row_data)
File "/Users/cole/PycharmProjects/Sites/virtualenvs/orchidislandcapital.com/lib/python2.7/site-packages/django/db/models/base.py", line 347, in __init__
setattr(self, field.attname, val)
AttributeError: can't set attribute
The definition for Orchid is class Orchid(FinancialReturnMixin, PeerPerformance). I haven't changed the FinancialReturnMixin, whose code is:
class FinancialReturnMixin(models.Model):
exclude_special_dividend = True
round_to = 4
shares_outstanding = models.FloatField(blank=True, null=True)
stock_price = models.FloatField(
verbose_name='quarter-end stock price',
blank=True, null=True)
class Meta:
abstract = True
app_label = 'snippets'
The second part of the Orchid class definition is PeerPerformance from which I have commented out the one change I had made. The definition for PeerPerformance is class PeerPerformance(DividendBookValueMixin) and all I did here was add 1 additional field to the model. DividendBookValueMixin is an abstract model.
I deleted my Orchid migrations, datatable and relevant south_migrationhistory entries. With class Orchid(models.Model), the Orchid model sets up fine. With class Orchid(PeerPerformance) the Orchid error remains. All my tests against PeerPerformance run. I can read and save PeerPerformance objects just fine.
>>> from peer.models import PeerPerformance as PP
>>> pp1 = PP.objects.get(id=1)
>>> pp1.dividend = 0.135
>>> pp1.save()
DividendBookValueMixin is the parent class for PeerPerformance. With class Orchid(DividendBookValueMixin) the error remains. All my tests agains DividendBookValueMixin run.
Any thoughts where to look?

(On linux)Sometime this occurs when you don't have read write permissions to the project directory or in virtualenv directory. Make sure you have apropriate read write permissions to the directory.

Related

Django Object is Not Serializable CommandError using Dumpdata with Natural Keys

I am trying to use 'natural keys' for serialization (docs) in a "manage.py dumpdata" command:
python manage.py dumpdata --natural-primary --natural-foreign --indent 4 --format json --verbosity 1 > tests\test_fixtures\test_db2.json
and I am getting the following error when I use --natural-foreign on other apps that use the Project or Task model (which they all must by design):
CommandError: Unable to serialize database: Object of type Project is not JSON serializable
Exception ignored in: <generator object cursor_iter at 0x000001EF62481B48>
Traceback (most recent call last):
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\site-packages\django\db\models\sql\compiler.py", line 1586, in cursor_iter
cursor.close()
sqlite3.ProgrammingError: Cannot operate on a closed database.
If I just dumpdata from this, the 'projects' app, it works, but other apps are built with entities related to Project or Task and there the --natural-foreign option fails.
The problem occurs when a model (say Question) calls for a natural_key from Task, which includes a for a natural_key from Project.
If I use the Pycharm Python Console to access querysets of Projects or Tasks ('q' here), this works:
serializers.serialize('json', q, indent=2, use_natural_foreign_keys=True, use_natural_primary_keys=True)
But if 'w' is a list of Question objects from another app that have a Task foreign key I get this error:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\site-packages\django\core\serializers\__init__.py", line 128, in serialize
s.serialize(queryset, **options)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\site-packages\django\core\serializers\base.py", line 115, in serialize
self.end_object(obj)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\site-packages\django\core\serializers\json.py", line 53, in end_object
json.dump(self.get_dump_object(obj), self.stream, **self.json_kwargs)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\__init__.py", line 179, in dump
for chunk in iterable:
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py", line 431, in _iterencode
yield from _iterencode_dict(o, _current_indent_level)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py", line 405, in _iterencode_dict
yield from chunks
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py", line 405, in _iterencode_dict
yield from chunks
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py", line 325, in _iterencode_list
yield from chunks
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py", line 438, in _iterencode
o = _default(o)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\site-packages\django\core\serializers\json.py", line 104, in default
return super().default(o)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Project is not JSON serializable
The models are:
# projects.models.py
class BaseModelWithHistory(models.Model):
history = HistoricalRecords(inherit=True)
natural_key_fields = ('id',) # default
class Meta:
abstract = True
def natural_key(self):
fieldlist = [getattr(self, fieldname) for fieldname in self.natural_key_fields]
return tuple(fieldlist)
# natural_key.dependencies = ['projects.Project', 'projects.Task'] # serialize these first.
class Project(BaseModelWithHistory):
"""
'Projects' group Tasks.
"""
project_name = models.CharField(max_length=200, default="development_project")
project_short_description = models.CharField(
max_length=500,
default="This is the default text.")
target_group = models.ManyToManyField(Group, blank=True)
objects = ProjectDiscreteManager()
natural_key_fields = ('project_name',)
class Task(BaseModelWithHistory):
number = models.PositiveIntegerField(default=0)
name = models.CharField(max_length=200, default='new task')
project = models.ForeignKey(Project, on_delete=models.CASCADE)
target_group = models.ManyToManyField(Group, blank=True)
app_label = models.CharField(max_length=80, choices=app_choices(), null=True, blank=True)
objects = discrete_manager_factory('project')
natural_key_fields = ('project', 'name', 'number')
Things that I wouldn't expect to cause this problem but I could certainly be wrong:
The ProjectDiscreteManager and others created by discrete_manager_factory() behave exactly as the default manager (models.Manager()), unless its called with a request from an identified user, in which case it adds a filter to see if that user is in the Group.
All models define the natural_keys tuple because the parent class defines it as ('id',); most models overwrite this with more representative fields.
With the natural_key.dependencies list set for all models to prioritize Project and then Task, I get a 'can't resolve dependencies' error for every other model. I think this ticket relates, but am not sure how to track down whether this fix is already in the Django 3.0.6 I'm using and I should just straighten up & fly right, or if my Han Solo 'this should wooork' will one day soon be rewarded. [Update: I worked out it is coming in Django 3.1.1, but I'm not sure that it is going to fix the "can't resolve dependencies" error I've created for myself.]

Django primary key does not exist

I have a script that I am using to populate an sqlite3 database from a .txt file in django however once the data is loaded in it I don't seem to be able to reference the objects with a pk. I can confirm the data has been loaded by doing ./manage.py shell and importing the City model and doing City.objects.all() shows that the models are loaded into the database but if I do City.object.get(pk=1) then it thinks that the City object does not exist.
I have had some issues with the database in the past so I recently did ./manage.py flush followed by a reinput of the data with the script. This is when things started to be an issue. Any ideas?
Also I know that I don't strictly need the uniqueID value but I don't think this is causing an issue, it hasn't in the past.
script for loading the data:
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mygame.settings")
from geogame.models import City
f = open("testing.txt", 'r').readlines()
i = 1
for line in f:
line = line.strip('\n')
line = line.split('\t')
line[6] = 1
line[7] = 100
c = City(name=line[1], uniqueID=i, xcoord=int(line[3]), ycoord=int(line[2]), country=line[4], population=line[5], times_played=line[6], average_distance=line[7], difficulty_rating=line[8])
c.save()
i+=1
the models.py file
from django.db import models
class City(models.Model):
name = models.CharField(max_length=50)
uniqueID = models.IntegerField(default=0)
ycoord = models.IntegerField(default=0)
xcoord = models.IntegerField(default=0)
country = models.CharField(max_length=50)
population = models.IntegerField(default=0)
times_played = models.IntegerField(default=0)
average_distance = models.FloatField(default=0)
difficulty_rating = models.FloatField(default=0)
def __unicode__(self):
return self.name
And the error message:
>>> City.objects.get(pk=1)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Library/Python/2.7/site-packages/django/db/models/manager.py", line 127, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Library/Python/2.7/site-packages/django/db/models/query.py", line 334, in get
self.model._meta.object_name
DoesNotExist: City matching query does not exist.
try adding id=i in c = City(). So that every time you create a new one, the id is adding 1 to it.
c = City(id=i, name=line[1], uniqueID=i,
xcoord=int(line[3]), ycoord=int(line[2]),
country=line[4],
population=line[5], times_played=line[6], average_distance=line[7],
difficulty_rating=line[8])
id in Your model has type AutoField. This type of firld automaticaly increment values when new row is added.
You can overwrite id when You create a new row
c = City(id=1, name='test', ...)
c.save()
City.objects.get(pk=1)
or read inserted id after save model
c = City(name='test', ...)
c.save()
lastId = c.pk
City.objects.get(pk=lastId)

Django: What is the correct way to query by foreign key field's id?

I have two models:
class Organization(models.Model):
title = models.CharField(max_length=100)
class Folder(models.Model):
organization = models.ForeignKey("Organization",related_name='folders')
title = models.CharField(max_length=50)
Now I want to filter the folder by organization id. so I tried:
Folder.objects.filter(organization= 1)
Folder.objects.filter(organization_id= 1)
Folder.objects.filter(organization__id= 1)
Folder.objects.filter(organization__pk= 1)
Folder.objects.filter(organization= Organization.objects.get(id=1))
Believe it or not everything returns the same.
So anybody know what is the correct way to query by foreign key field's id?
update
but when try to create folder by:
Folder.objects.create(organization__id=1,title='hello')
got error:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/suhail/.virtualenvs/heybadges/local/lib/python2.7/site-packages/django/db/models/manager.py", line 92, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/suhail/.virtualenvs/heybadges/local/lib/python2.7/site-packages/django/db/models/query.py", line 370, in create
obj = self.model(**kwargs)
File "/home/suhail/.virtualenvs/heybadges/local/lib/python2.7/site-packages/django/db/models/base.py", line 452, in __init__
raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0])
TypeError: 'organization__id' is an invalid keyword argument for this function
but Folder.objects.create(organization_id=1,title='hello') works fine.
Django docs say that you should use Folder.objects.filter(organization__pk=1) in most cases.
Answer to the update:
Probably Folder.objects.create(organization_id=1,title='hello') works because Django appends "_id" to the field name to create its database column name.

Django Foreign Keys Breaking with Multi-Table Inheritance

The following code works as I expect it to:
class General(Model):
pass
class Captain(Model):
general = ForeignKey('General',related_name='captains')
I can create a general, add captains, and doing "general.captains" works as expected.
But when both these classes inherit from a base class that might have extra info, disaster strikes.
class Officer(Model):
pass
class General(Officer):
pass
class Captain(Officer):
general = ForeignKey('General',related_name='captains')
>>> g = General()
>>> g.captains
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Python27\lib\site-packages\django\db\models\fields\related.py", line
391, in __get__
self.related.model._default_manager.__class__)
File "C:\Python27\lib\site-packages\django\db\models\fields\related.py", line
469, in create_manager
getattr(instance, attname)}
File "C:\Python27\lib\site-packages\django\db\models\fields\related.py", line
301, in __get__
raise self.field.rel.to.DoesNotExist
DoesNotExist
Any idea what might be happening here, and how I could fix it?
It should work if you define your Officer model explicitly as abstract
class Meta:
abstract = True
So as a test i slightly modified your base class:
class Officer(models.Model):
name = models.CharField(max_length=255)
class Meta:
abstract = True
And the following works:
>>> General(name='Warfield').save()
>>> G = General.objects.all()[0]
>>> Captain(name='Picard', general=G).save()
>>> C = Captain.objects.all()[0]
>>> C.general.name
u'Warfield'
>>> G.captains.all()[0].name
u'Picard'

Django ManyToManyField error

I am using Django's ManyToManyField, and when i try to add data to it, i get the following error:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/purav/Desktop/socmov/fbcon/models.py", line 165, in getMovieInfo
movie.genre.add( G )
File "/usr/local/lib/python2.6/dist-packages/django/db/models/fields/related.py", line 503, in add
self._add_items(self.source_field_name, self.target_field_name, *objs)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/fields/related.py", line 563, in _add_items
(obj, self.instance._state.db, obj._state.db))
ValueError: Cannot add "<Genre: Genre object>": instance is on database "None", value is on database "default"
I am using Django 1.3, and i following is a part of my code:
class Genre(models.Model):
gid = models.IntegerField(primary_key = True)
name = models.CharField(max_length = 20)
class Movie(models.Model):
mid = models.IntegerField(primary_key = True)
name = models.CharField(max_length = 100)
genre = models.ManyToManyField("Genre")
This is where the error occurs:
G = Genre.objects.get(gid = obj[i]['id'])
print G.name, G.gid
movie.genre.add( G )
It is guaranteed that obj[i]['id'] will be found inside Genre. Can someone please help me?
You need to save the movie instance after creating it, before you can add m2m relations.