New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix dereferencing embedded documents refs and dereferencing tests. #17
Conversation
Reproduce bug when dereference function does not dereference refs in embedded documents from list ListField(EmbeddedDoc(ReferenceField(X))). Instead it peforms additional call to db using dereference_id function from __get__ method of ReferenceField.
Dereference function does not go into Embedded document from list when traversing model to attach dereferenced documents to reference fields.
This test save empty Post object while it defines a title (which is CharField) as pk. That forces to store post object with _id as ObjectId value not a string. So post.delete() does not work and does not delete any database objects as the post's pk is string not an ObjectId. Test is still pass as comment.post reference field value is a string too. To fix that while saving Post a title should be specified.
Thanks for the pull request! These fixes look good to me. Thanks also for the test case. For (2), I think there's another problem here, too. I think the issue is that there's no ValidationError raised when saving a model whose primary key has not been given, when the primary key isn't implicit. Some examples: class PostTitlePK(MongoModel):
title = fields.CharField(primary_key=True)
class PostImplicitPK(MongoModel):
title = fields.CharField()
# This should raise ValidationError, since we explicitly defined
# `title` as the primary_key, but it hasn't been given a value.
# `title` should be required:
# ValidationError: {'title': ['field is required']}
post = PostTitlePK().save()
# This is ok. There is no primary_key declared on the model, so the
# primary_key is a hidden ObjectIdField, which will be filled in when
# we call save().
post_ok = PostImplicitPK().save() I think that So, I think your fixes all look good, but there's another change needed. We need to set Do you agree? Would you like to make this fix as well? Thank you so much for your time and effort to improve this project! |
Yes, I agree. I'll try to make this fix too. Where is the best place to put test for this fix? |
I think Also, I wouldn't be surprised if fixing this bug causes other tests to fail, since there are probably other places where we are trying to save documents with an explicit primary_key that don't have a value for it. The solution will be the same: to provide a value for the primary_key field. |
If some model's field is explicitly defined as primary key that field should become required. If such field is not given value then while model validation the ValidationError should be raised. - Add test for issue. - Add fix. - Fix other tests that do not set a value to primary key field as it is required now.
Would it be ok if I also add a small fix to make clone = QuerySet(model=model or self._model, query=query or self._query) with clone = type(self)(model=model or self._model, query=query or self._query) ? |
Ha! The same fix for clone is also proposed in this pull request: https://github.com/mongodb/pymodm/pull/13/files#diff-36aa0eb7af6d66c2411da533ad499995R63. Go for it. Thanks again for your hard work on this. |
Thank you for fixing this and updating all the tests. Your work here will be part of the forthcoming 0.3.1 release. Thanks again! |
What does these changes do:
ListField(EmbeddedDoc(ReferenceField(X)))
. It performs an additional call to db using dereference_id function while accessing the field.test test.test_dereference.DereferenceTestCase.test_reference_not_found
. It saves an emptyPost
model which has title as a pk. That forces to store post document with _id as anObjectId
. Sopost.delete()
does not actually delete any documents from database.