python 2.7.8, latest mongoengine.zip from master:
mongoengine/fields.py, line 990
def validate(self, value):
if not isinstance(value, (self.document_type, DBRef)):
self.error("A ReferenceField only accepts DBRef or documents")
if isinstance(value, Document) and value.id is None:
self.error('You can only reference documents once they have been '
'saved to the database')
first "if" gives the following code
s = Shift.objects.get(id='554ad0c18a5da50025b7c7c3')
print s.guard.fname
#guard = Guard.objects.get(id='55355d7083ba88e23f8b4569')
guard = Guard.objects.get(id='54d4361183ba88c24a8b4567')
print guard.fullname
s.guard = guard
s.save()
mongoengine.errors.ValidationError: A ReferenceField only accepts DBRef or documents
traceback:
https://gist.github.com/saritasa/27d82f33e3cc33afe1cb
If I run it again - everything works. If I uncomment the first guard and comment 2nd guard, I get this error again. Run 4th time - and error gone.
value is ObjectId type, when I debug code.
Sample data:
{
"_id" : ObjectId("554ad0c18a5da50025b7c7c3"),
"parent" : ObjectId("55241c448a5da5002616ede5"),
"type" : "reassignment",
"date" : ISODate("2015-05-15T00:00:00.000Z"),
"school" : ObjectId("55241a8983ba889a678b4567"),
"location" : ObjectId("55241ae583ba88d46c8b4567"),
"guard" : ObjectId("54d4361183ba88c24a8b4567"),
"name" : "1st shift",
"weekday" : 5,
"start" : "08:00:00",
"finish" : "08:30:00",
"start_sec" : 28800,
"finish_sec" : 30600,
"weight" : 28800,
"holidays" : [],
"created_at" : ISODate("2015-05-07T02:41:05.618Z"),
"updated_at" : ISODate("2015-05-11T10:01:58.139Z"),
"guard_name" : "Guard2Vadik alt Kuz",
"school_name" : "VictorHigh",
"location_name" : "Joslin / Gard",
"guard_phone" : "1231231234",
"parent_cache" : {
"_id" : ObjectId("55241c448a5da5002616ede5"),
"finish" : "08:30:00",
"weight" : 28800,
"start_sec" : 28800,
"finish_sec" : 30600,
"start" : "08:00:00",
"guard" : ObjectId("552411f883ba8842658b4567"),
"type" : "regular"
}
}
Full shift class is here:
https://gist.github.com/saritasa/ad9387a1259141db4a04
any ideas?
Not really, but this doesn't sound good... There is quite a bit to do here, but if I have time, I may inspect that further. Else, feel free to submit a PR, at least with a proper (failing) test, even better with the fix :-)
I had a similar problem and apparently it occurs when the ReferenceField's document class is abstract.
In my case, inside the ReferenceField.validate method, type(value) was myapp.mymodule.documents.subclassmodule.FooBar while self.document_type was myapp.mymodule.documents..Bar (there were actually two dots between documents and Bar).
FooBar is a subclass of Bar (more precisely, it was declared as FooBar(FooBarSerializer, Bar):), but isinstance(value, self.document_type) evaluated to False (so did issubclass(type(value), self.document_type) although I believe that's exactly equivalent).
Hope this helps.
try using
s.guard = guard..to_dbref()
s.save()
@rahulrameshan you are right, thank you.
Most helpful comment
try using
s.guard = guard..to_dbref()
s.save()