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

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.

Related

im not able to makemigrations to my already built model after extending user model to it in django

im just stuck with error while making migrations to my django project.
in my project which is already 50% dveloped i use owner model to represent owner of shop and then i used user model for login and for registration purpose.
so i tried to use user model in my owner model so i could utilise both model effectively with additional fields.
i tried to extend user model in owner model using onetoone field.
after doing that i was not able to do migrations so i deleted all migrations files but after that it was start giving this error while doing migrations:-
py manage.py makemigrations
Traceback (most recent call last):
File "manage.py", line 21, in <module>
main()
File "manage.py", line 17, in main
execute_from_command_line(sys.argv)
File "C:\Users\Mayur\PycharmProjects\StartUp\venv\lib\site-packages\django\core\management\__init__.py", line 401, in execute_from_command_line
utility.execute()
File "C:\Users\Mayur\PycharmProjects\StartUp\venv\lib\site-packages\django\core\management\__init__.py", line 395, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Users\Mayur\PycharmProjects\StartUp\venv\lib\site-packages\django\core\management\base.py", line 328, in run_from_argv
self.execute(*args, **cmd_options)
File "C:\Users\Mayur\PycharmProjects\StartUp\venv\lib\site-packages\django\core\management\base.py", line 369, in execute
output = self.handle(*args, **options)
File "C:\Users\Mayur\PycharmProjects\StartUp\venv\lib\site-packages\django\core\management\base.py", line 83, in wrapped
res = handle_func(*args, **kwargs)
File "C:\Users\Mayur\PycharmProjects\StartUp\venv\lib\site-packages\django\core\management\commands\makemigrations.py", line 87, in handle
loader = MigrationLoader(None, ignore_no_migrations=True)
File "C:\Users\Mayur\PycharmProjects\StartUp\venv\lib\site-packages\django\db\migrations\loader.py", line 49, in __init__
self.build_graph()
File "C:\Users\Mayur\PycharmProjects\StartUp\venv\lib\site-packages\django\db\migrations\loader.py", line 274, in build_graph
raise exc
File "C:\Users\Mayur\PycharmProjects\StartUp\venv\lib\site-packages\django\db\migrations\loader.py", line 248, in build_graph
self.graph.validate_consistency()
File "C:\Users\Mayur\PycharmProjects\StartUp\venv\lib\site-packages\django\db\migrations\graph.py", line 195, in validate_consistency
[n.raise_error() for n in self.node_map.values() if isinstance(n, DummyNode)]
File "C:\Users\Mayur\PycharmProjects\StartUp\venv\lib\site-packages\django\db\migrations\graph.py", line 195, in <listcomp>
[n.raise_error() for n in self.node_map.values() if isinstance(n, DummyNode)]
File "C:\Users\Mayur\PycharmProjects\StartUp\venv\lib\site-packages\django\db\migrations\graph.py", line 58, in raise_error
raise NodeNotFoundError(self.error_message, self.key, origin=self.origin)
django.db.migrations.exceptions.NodeNotFoundError: Migration listings.0001_initial dependencies reference nonexistent parent node ('owners', '0001_initial')
here is my Owner Model :-
from django.db import models
from django.contrib.auth.models import User
class Owner(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE, default=False)
name=models.CharField(max_length=200)
photo=models.ImageField(upload_to='photos/%Y/%m/%d/')
description=models.TextField(blank=True)
phone=models.CharField(max_length=20)
email=models.CharField(max_length=20)
def __str__(self):
return self.name
im hoping that will get help on this because i'm totally stuck here and also not getting how to tackle this problem.
You are using the term "migration folder of my django project" (in a comment above), and that is wrong -- each app in your project has its own migration folder. Specifically, there is still a migration in your "listings" app, and it lists as a dependency one of the migrations you deleted.
after reviewing and debugging that stack trace i finally get rid of that problem.
i delete the migration file 0001 from my listing app which was having relationship with Owner Model and then when i run makemigrations command it didn't given me any error or exception like i mentioned above.

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 Model - cannot serialize into migration files

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.

Django Haystack update index faster

I've been using Django Haystack for a while now and it's great! I have a rather heavy site with data which needs to be updated from time to time (15 to 30 mins).
When using the python manage.py update_index it takes lots of time to update the data. Is there a way to speed this up? Or maybe update only changed data if possible..
I'm currently using Django Haystack 1.2.7 with Solr as backend and Django 1.4.
Thanks!!!
EDIT:
Yes I've tried reading that part of the documentation but what I really need is a way to speed the indexing up. Maybe update only recent data instead of updating all. I've found get_updated_field but don't know how to use it. In the documentation it's only mentioned why it's used but no real examples are shown.
EDIT 2:
start = DateTimeField(model_attr='start', null=True, faceted=True, --HERE?--)
EDIT 3:
Ok i've implemented the solution bellow but when i tried rebuild_index (with 45000 data) it almost crashed my computer. After 10 mins of waiting an error appeared:
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 443, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 382, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 196, in run_from_argv
self.execute(*args, **options.__dict__)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 232, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python2.7/dist-packages/haystack/management/commands/rebuild_index.py", line 16, in handle
call_command('update_index', **options)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 150, in call_command
return klass.execute(*args, **defaults)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 232, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python2.7/dist-packages/haystack/management/commands/update_index.py", line 193, in handle
return super(Command, self).handle(*apps, **options)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 304, in handle
app_output = self.handle_app(app, **options)
File "/usr/local/lib/python2.7/dist-packages/haystack/management/commands/update_index.py", line 229, in handle_app
do_update(index, qs, start, end, total, self.verbosity)
File "/usr/local/lib/python2.7/dist-packages/haystack/management/commands/update_index.py", line 109, in do_update
index.backend.update(index, current_qs)
File "/usr/local/lib/python2.7/dist-packages/haystack/backends/solr_backend.py", line 73, in update
self.conn.add(docs, commit=commit, boost=index.get_field_weights())
File "/usr/local/lib/python2.7/dist-packages/pysolr.py", line 686, in add
m = ET.tostring(message, encoding='utf-8')
File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1127, in tostring
ElementTree(element).write(file, encoding, method=method)
File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 821, in write
serialize(write, self._root, encoding, qnames, namespaces)
File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 940, in _serialize_xml
_serialize_xml(write, e, encoding, qnames, None)
File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 940, in _serialize_xml
_serialize_xml(write, e, encoding, qnames, None)
File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 915, in _serialize_xml
write("<" + tag)
MemoryError
get_updated_field should return a string that contains the name of the attribute on the model that contains the date that the model was updated (haystack docs). A DateField with auto_now=True would be ideal for that (Django docs).
For example, my UserProfile model has a field named updated
models.py
class UserProfile(models.Model):
user = models.ForeignKey(User)
# lots of other fields snipped
updated = models.DateTimeField(auto_now=True)
search_indexes.py
class UserProfileIndex(SearchIndex):
text = CharField(document=True, use_template=True)
user = CharField(model_attr='user')
user_fullname = CharField(model_attr='user__get_full_name')
def get_model(self):
return UserProfile
def get_updated_field(self):
return "updated"
Then when I run ./manage.py update_index --age=10 it only indexes the user profiles updated in the last 10 hours.

django-haystack - Updating index after adding new field to index causing error

I have a django site which uses Haystack with the Xapian backend for search indexing. I've added a new field to one of the models being indexed, then added that field to the SearchIndex for that model. I've run:
python manage.py update_index
To update the index, but I'm getting the following error:
Traceback (most recent call last):
File "manage.py", line 11, in <module>
execute_manager(settings)
File "/usr/local/lib/python2.6/dist-packages/django/core/management/__init__.py", line 438, in execute_manager
utility.execute()
File "/usr/local/lib/python2.6/dist-packages/django/core/management/__init__.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python2.6/dist-packages/django/core/management/base.py", line 191, in run_from_argv
self.execute(*args, **options.__dict__)
File "/usr/local/lib/python2.6/dist-packages/django/core/management/base.py", line 220, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python2.6/dist-packages/django_haystack-1.0.1_final-py2.6.egg/haystack/management/commands/update_index.py", line 51, in handle
self.handle_app(None, **options)
File "/usr/local/lib/python2.6/dist-packages/django_haystack-1.0.1_final-py2.6.egg/haystack/management/commands/update_index.py", line 107, in handle_app
index.backend.update(index, small_cache_qs[start:end])
File "/usr/local/lib/python2.6/dist-packages/xapian_haystack-1.1.3beta-py2.6.egg/xapian_backend.py", line 204, in update
data = index.prepare(obj)
File "/usr/local/lib/python2.6/dist-packages/django_haystack-1.0.1_final-py2.6.egg/haystack/indexes.py", line 102, in prepare
self.prepared_data[field_name] = field.prepare(obj)
File "/usr/local/lib/python2.6/dist-packages/django_haystack-1.0.1_final-py2.6.egg/haystack/fields.py", line 119, in prepare
return self.convert(super(CharField, self).prepare(obj))
File "/usr/local/lib/python2.6/dist-packages/django_haystack-1.0.1_final-py2.6.egg/haystack/fields.py", line 75, in prepare
raise SearchFieldError("The model '%s' has an empty model_attr '%s' and doesn't allow a default or null value." % (repr(current_object), attr))
haystack.exceptions.SearchFieldError: The model 'None' has an empty model_attr 'address_county' and doesn't allow a default or null value.
The versions I'm using are django 1.2 and django-haystack 1.0.1. Upgrading these to the newest version isn't an option for me at the moment.
I found the answer. The clue was in the error message (which, as we all know, doesn't always happen!):
The model 'None' has an empty model_attr 'address_county' and doesn't allow a default or null value.
My model field had been created with blank=True, null=True. This caused the error, so I removed those and added default='' and this enabled me to update the index with no error. Hope this helps someone sometime!
I was facing the same issue when indexing the phone field of my modal. I simply add null=True to the solr field in search_index.py
phone = CharField(model_attr="phone", null=True)