Django Model - cannot serialize into migration files - django

I have 2 models Car and Offer. The car table is an existing table filled with vehicle specifications. In the django admin I want to map an offer to an existing car in the specs table. This means that when a click on an offer in admin, I want to be able to see a list with all cars - find the correct one - and save it on the offer. Ive done this by populating the foreignkey field with a list of choices based on the the existing car objects.
models.py:
class Car(models.Model):
brand = models.TextField(max_length=300, default= "")
model = models.TextField(max_length=300, default= "")
edition = models.TextField(max_length=300, default= "")
engineVolume = models.FloatField(default=0.0)
def __unicode__(self):
return smart_unicode(self.brand)
carIds = []
idx = 1
for car in Car.objects.all():
carIds.append((idx, car))
idx = idx + 1
class Offer(models.Model):
stringUrl = models.TextField(max_length=300)
extractionDate = models.DateTimeField(default=datetime.datetime.now, blank=True)
cars = models.ForeignKey(Car, default= "", choices=carIds, null=True, to_field='id')
this works perfectly. I click on an offer in admin and I see a selectionbox populated with all existing cars. I find the correct car, save it, and the offers´s foreignkey car id in the database points to the correct vehicle.
But suddenly when I want to make later migrations django says it cannot serialze the car object?
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python2.7/site- packages/django/core/management/__init__.py", line 338, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 330, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 390, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 441, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python2.7/site-packages/django/core/management/commands/makemigrations.py", line 143, in handle
self.write_migration_files(changes)
File "/usr/local/lib/python2.7/site-packages/django/core/management/commands/makemigrations.py", line 171, in write_migration_files
migration_string = writer.as_string()
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 166, in as_string
operation_string, operation_imports = OperationWriter(operation).serialize()
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 124, in serialize
_write(arg_name, arg_value)
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 87, in _write
arg_string, arg_imports = MigrationWriter.serialize(_arg_value)
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 377, in serialize
return cls.serialize_deconstructed(path, args, kwargs)
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 268, in serialize_deconstructed
arg_string, arg_imports = cls.serialize(arg)
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 303, in serialize
item_string, item_imports = cls.serialize(item)
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 303, in serialize
item_string, item_imports = cls.serialize(item)
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 465, in serialize
"topics/migrations/#migration-serializing" % (value, get_docs_version())
`enter code here`ValueError: Cannot serialize: <Car: Nissan>
There are some values Django cannot serialize into migration files.
For more, see https://docs.djangoproject.com/en/1.8/topics/migrations/#migration- serializing
I have no idea why this error occurs. I' m new to django and the just starting with the admin. I´ve been reading up on serialzation and deconstruction but cant see how to apply it here? Perhaps I should follow a different route to achieve what I want?

In my case I was tring to add a field like:
task = models.ForeignKey(Task, on_delete=models.CASCADE, default=Task.objects.first())
but corrected this by using:
task = models.ForeignKey(Task, on_delete=models.CASCADE, default=Task.objects.first().pk)

In a nutshell you don't need choices at all.
choices, although can be any iterable and can be modified, is more suited for static data.
Afterwards, this piece of code
carIds = []
idx = 1
for car in Car.objects.all():
carIds.append((idx, car))
idx = idx + 1
achieves nothing.
First, you are not filtering the choices in any way, just converting them to a list of tuples. Second, having a ForeignKey automatically provides choices from the referenced model's unfiltered queryset e.g. Car.objects.all().
So you could just drop choices, and if you need filtering in ModelForm and admin use ForeignKey.limit_choices_to instead.

Related

Expanding the list of relationship field arguments

I’m looking for a way to expand the list of relationship field arguments, e.g. to add a predicate for each direction of the relation. My first guess was to define a subclass of models.ForeignKey
class NewForeignKey(models.ForeignKey):
def __init__(self, parent, pred='', reverse_pred='', **kwargs):
self.pred = pred,
self.reverse_pred = reverse_pred
super(NewForeignKey, self).__init__(parent, **kwargs)
Then use this subclass in my models as in the following example:
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = NewForeignKey (Question,
pred="refers to",
reverse_pred="includes",
on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
Initially, this seemed to work fine, however, when I tried to pass it through makemigrations it failed with the following error message:
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "C:\Python27\lib\site-packages\django\core\management\__init__.py", line 354, in execute_from_command_line
utility.execute()
File "C:\Python27\lib\site-packages\django\core\management\__init__.py", line 346, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Python27\lib\site-packages\django\core\management\base.py", line 394, in run_from_argv
self.execute(*args, **cmd_options)
File "C:\Python27\lib\site-packages\django\core\management\base.py", line 445, in execute
output = self.handle(*args, **options)
File "C:\Python27\lib\site-packages\django\core\management\commands\makemigrations.py", line 99, in handle
ProjectState.from_apps(apps),
File "C:\Python27\lib\site-packages\django\db\migrations\state.py", line 178, in from_apps
model_state = ModelState.from_model(model)
File "C:\Python27\lib\site-packages\django\db\migrations\state.py", line 354, in from_model
e,
TypeError: Couldn't reconstruct field question on polls.Choice: __init__() takes at least 2 arguments (1 given)
To make things even simpler I tried from scratch to migrate as follows:
first without the FK,
then added the FK as models.ForeignKey and
finally replaced models.ForeignKey with NewForeignKey
Migrations after step (1) and (2) were successful (obviously). makemigrations after step (3) fails all the time with the same result whether I skip step (2) or not.
Digging deeper, I couldn’t find an explanation why this shouldn’t be possible. I understand that Django models have to be subclassed from django.db.models.Model (see here), but this isn’t the case with models.ForeignKey.
A clarification on this issue and/or any suggestions for a workaround or a clever alternative that would allow the use of additional relationship field arguments would be appreciated.

Django many-to-many relationship - database "None"?

I've been bashing my head on this problem for the past two hours or so and was wondering if someone could help me out. With this code:
ann = Announcement(**params)
ann.save()
# Push this announcement to each competitor's unread announcements queue
for competitor in Competitor.objects.all():
competitor.unread_announcements.add(ann)
#ann.competitor_set.add(competitor)
and the relevant model fields:
class Announcement(models.Model):
id = models.IntegerField(primary_key=True)
title = models.CharField(max_length=80, blank=False)
body = models.TextField(blank=False)
posted = models.DateTimeField(auto_now_add=True)
# ...
class Competitor(models.Model):
id = models.AutoField(primary_key=True)
unread_announcements = models.ManyToManyField('Announcement')
When we get to the line adding the announcement to the queue, we get this error:
Traceback (most recent call last):
File "./manage.py", line 16, in <module>
execute_from_command_line(sys.argv)
File "/usr/lib/python3.5/site-packages/django/core/management/__init__.py", line 350, in execute_from_command_line
utility.execute()
File "/usr/lib/python3.5/site-packages/django/core/management/__init__.py", line 342, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/lib/python3.5/site-packages/django/core/management/base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/lib/python3.5/site-packages/django/core/management/base.py", line 399, in execute
output = self.handle(*args, **options)
File "/home/cam/Documents/Programming/web/pactf-web2/django/ctflex/management/commands/announce.py", line 40, in handle
ann.competitor_set.add(competitor)
File "/usr/lib/python3.5/site-packages/django/db/models/fields/related_descriptors.py", line 843, in add
self._add_items(self.source_field_name, self.target_field_name, *objs)
File "/usr/lib/python3.5/site-packages/django/db/models/fields/related_descriptors.py", line 963, in _add_items
(obj, self.instance._state.db, obj._state.db)
ValueError: Cannot add "<Competitor: <Competitor #1 'cam'>>": instance is on database "None", value is on database "default"
All my research on the topic has shown that this error is caused when one or both of the relevant objects hasn't been saved in the database. However, in this case, I'm literally saving the announcement two lines beforehand, and the competitor object already lives in the database. So, what am I doing wrong?
Try omitting the id field of your Models. Since you're noting using the default id filed Django provided.

Django South schemamigration error AttributeError: 'Options' object has no attribute 'index_together'

I am working on a Django web app with south for db migration. I am quite new to south, and django as well. I tried using south with the official tutorials, however it failed with an exception: AttributeError: 'Options' object has no attribute 'index_together'.
I run the south command like this:
python manage.py schemamigration southtut --initial
The southtut models is this:
class Knight(models.Model):
name = models.CharField(max_length=100)
of_the_round_table = models.BooleanField()
My project models is this:
class Author(models.Model):
name = models.CharField(max_length=64)
authorId = models.CharField(max_length=32)
def __unicode__(self):
return self.name
class Meta:
db_table="Author"
class Video(models.Model):
videoId = models.CharField(max_length=32)
videoUrl = models.URLField(max_length=200)
author = models.ForeignKey(Author, null=True, related_name="videos", on_delete=models.SET_NULL)
class Meta:
db_table="Video"
class User(models.Model):
token = models.CharField(max_length=50, null=True)
favs = models.ManyToManyField(Video, related_name="fans", db_table="VideoUserR")
class Meta:
db_table = "User"
The whole error message I got is as below:
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/Library/Python/2.7/site-packages/django/core/management/__init__.py", line 443, in execute_from_command_line
utility.execute()
File "/Library/Python/2.7/site-packages/django/core/management/__init__.py", line 382, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Library/Python/2.7/site-packages/django/core/management/base.py", line 196, in run_from_argv
self.execute(*args, **options.__dict__)
File "/Library/Python/2.7/site-packages/django/core/management/base.py", line 232, in execute
output = self.handle(*args, **options)
File "/Library/Python/2.7/site-packages/South-0.7.6-py2.7.egg/south/management/commands/schemamigration.py", line 151, in handle
for action_name, params in change_source.get_changes():
File "/Library/Python/2.7/site-packages/South-0.7.6-py2.7.egg/south/creator/changes.py", line 460, in get_changes
model_defs = freeze_apps([self.migrations.app_label()])
File "/Library/Python/2.7/site-packages/South-0.7.6-py2.7.egg/south/creator/freezer.py", line 37, in freeze_apps
model_defs[model_key(model)] = prep_for_freeze(model)
File "/Library/Python/2.7/site-packages/South-0.7.6-py2.7.egg/south/creator/freezer.py", line 78, in prep_for_freeze
fields['Meta'] = remove_useless_meta(modelsinspector.get_model_meta(model))
File "/Library/Python/2.7/site-packages/South-0.7.6-py2.7.egg/south/modelsinspector.py", line 441, in get_model_meta
meta_def[kwd] = get_value(model._meta, defn)
File "/Library/Python/2.7/site-packages/South-0.7.6-py2.7.egg/south/modelsinspector.py", line 258, in get_value
value = get_attribute(field, attrname)
File "/Library/Python/2.7/site-packages/South-0.7.6-py2.7.egg/south/utils/__init__.py", line 38, in get_attribute
value = getattr(value, part)
AttributeError: 'Options' object has no attribute 'index_together'
Thanks
It's bug in south 0.8. Just update to 0.8.1 or newer and all be good.
It looks like this is because you are trying to use index_together option in Meta section of your model. But this option is available only for django 1.5+ and i guess that you run it on a less recent version of django.
I updated my django to 1.5.1, and this error disappeared. I have no idea how the 'index_together' come out, but since it is available in django 1.5.1, it get what it needs.

Django: QuerySet error

I have a test view where one of the data aggregation queries throws an eror that I don't understand. I would appreciate it if someone could comment on this and point me in the right direction. This is my first django project and I'm traversing the learning curve so please bear with me:
Code:
biz_group = BusinessGroup.objects.get(group_manager=user)
group_team = BusinessGroupToTeams.objects.get(group_id=biz_group.group_id)
which throws the error:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/django/db/models/manager.py", line 143, in get
return self.get_query_set().get(*args, **kwargs)
File "/usr/lib/python2.7/dist-packages/django/db/models/query.py", line 394, in get
num = len(clone)
File "/usr/lib/python2.7/dist-packages/django/db/models/query.py", line 90, in __len__
self._result_cache = list(self.iterator())
File "/usr/lib/python2.7/dist-packages/django/db/models/query.py", line 301, in iterator
for row in compiler.results_iter():
File "/usr/lib/python2.7/dist-packages/django/db/models/sql/compiler.py", line 775, in results_iter
for rows in self.execute_sql(MULTI):
File "/usr/lib/python2.7/dist-packages/django/db/models/sql/compiler.py", line 840, in execute_sql
cursor.execute(sql, params)
File "/usr/lib/python2.7/dist-packages/django/db/backends/util.py", line 41, in execute
return self.cursor.execute(sql, params)
File "/usr/lib/python2.7/dist-packages/django/db/backends/postgresql_psycopg2/base.py", line 58, in execute
six.reraise(utils.DatabaseError, utils.DatabaseError(*tuple(e.args)), sys.exc_info()[2])
File "/usr/lib/python2.7/dist-packages/django/db/backends/postgresql_psycopg2/base.py", line 54, in execute
return self.cursor.execute(query, args)
DatabaseError: column businessgroup_to_teams.id does not exist
LINE 1: SELECT "businessgroup_to_teams"."id", "businessgroup_to_teams"...
The BusinessGroupToTeams model looks like this:
class BusinessAreaToTeams(models.Model):
group_id = models.DecimalField(max_digits=65535, decimal_places=65535)
team_id = models.DecimalField(max_digits=65535, decimal_places=65535)
class Meta:
db_table = 'businessgroup_to_teams'
I am not querying on "id" and have no model field of "id". Can someone explain what I'm doing wrong here?
It looks like you are trying to define a crossover table with BusinessAreaToTeams. Instead of having group_id and team_id be DecimalFields which contain the raw ID, you should define
group = ForeignKey(BusinessGroup)
team = ForeignKey(BusinessTeam) # guessing the model name here
This will create a group_id and team_id field in your table and will allow you to manage the relationship easily using django's QuerySets. Please take a look at Chapter 10 of the Django book for an introduction to this topic.
here you have not mention any primary key so the django automatically created a primary key
name id.
here you can make your primary key like this:
group_id = models.DecimalField(max_digits=65535, decimal_places=65535, primary_key=True)
it will then make the group_id as primary key.

Extending Django FlatPages to use MPTT

Preface: I was writing my own Page app that used MPTT and a custom page model. This was working for me, but FlatPages is more refined than my custom Page Model and so I'm leaning toward just extending it.
from django.db import models
from django.contrib.flatpages.models import FlatPage
from mptt.models import MPTTModel
class ExtendedFlatPage(FlatPage, MPTTModel):
parent = models.ForeignKey('ExtendedFlatPage', null=True, blank=True, default=None, related_name="children", help_text="Hierarchical parent page (if any)")
class Meta:
ordering = ['flatpages__url']
order_with_respect_to = 'parent'
verbose_name = 'page'
verbose_name_plural = 'pages'
class MPTTMeta:
left_attr = 'mptt_left'
right_attr = 'mptt_right'
level_attr = 'mptt_level'
order_insertion_by = ['title']
def __unicode__(self):
return self.url
This almost works, except throws an error when I go to run python manage.py syncdb
Error:
iMac:cms colab$ python manage.py syncdb
Creating tables ...
Creating table my_flatpages_extendedflatpage
Traceback (most recent call last):
File "manage.py", line 14, in <module>
execute_manager(settings)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/__init__.py", line 438, in execute_manager
utility.execute()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/__init__.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/base.py", line 191, in run_from_argv
self.execute(*args, **options.__dict__)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/base.py", line 220, in execute
output = self.handle(*args, **options)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/base.py", line 351, in handle
return self.handle_noargs(**options)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/commands/syncdb.py", line 101, in handle_noargs
cursor.execute(statement)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/db/backends/util.py", line 34, in execute
return self.cursor.execute(sql, params)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/db/backends/mysql/base.py", line 86, in execute
return self.cursor.execute(query, args)
File "build/bdist.macosx-10.6-intel/egg/MySQLdb/cursors.py", line 174, in execute
File "build/bdist.macosx-10.6-intel/egg/MySQLdb/connections.py", line 36, in defaulterrorhandler
django.db.utils.DatabaseError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 2")
If anyone could point me in the right direction, I would greatly appreciate it. Thanks!
replace
class ExtendedFlatPage(FlatPage, MPTTModel):
with
class ExtendedFlatPage(MPTTModel, FlatPage):
This will allow MPTTModel class to override FlatPage attributes and methods.
#comment
It appears that something (an attribute, method) in FlatPage model overrides something in MPTTModel cousing this error.
order of classes you import from is important. here's an example:
class A:
attribute = 1
class B:
attribute = 2
class C(A,B):
pass
class C attribute value will be 1.