Comments (17)
Mongoengine Serializer does not support EmbeddedDocument, or ListField, yet.
Instead, the serializer uses depth
for deciding whether reference(with pk) or embed Documents.
As you see on https://pythonhosted.org/django-rest-framework-mongoengine/#usage ,
you should set your ReferenceField
s on model and also your depth properly.
For your case, you should declare EmbeddedDescriptionsReference
as Document and set depth
at least 1 (consider your JSON depth level)
Hope that clarifies your issue
from django-rest-framework-mongoengine.
Thanks. I don't think that will work in my case because the embedded document is part of the parent document, not a document in a different collection. With the suggested usage in the documentation I received the following error when querying from the db:
id must be an instance of (bytes, str, ObjectId), not <class 'dict'>
from django-rest-framework-mongoengine.
Couldn't think of anything to overcome querying issue, could you post querying code?
Also, I would appreciate any pull requests regarding serializing ListFields
from django-rest-framework-mongoengine.
I get the error when I try to query from the database:
Products.objects.get(id=...)
This is if I change my code to the following:
class EmbeddedDescriptionsReference(Document):
long_desc = StringField()
short_desc = StringField()
meta = {'allow_inheritance': False}
class Products(DynamicDocument):
descriptions = ReferenceField(EmbeddedDescriptionsReference)
meta = {'collection': 'products'}
class ProductsSerializer(rest_framework_mongoengine.serializers.MongoEngineModelSerializer):
class Meta:
model = Products
fields = ('descriptions',)
This would be if the documents in the products collection are in the following form:
{
'_id': ObjectId("..."),
'descriptions': {
'long_desc': 'Long description',
'short_desc': 'Short description'
}
}
Yeah I'll take a look at the code and see if I have any ideas for embedded documents and lists
from django-rest-framework-mongoengine.
There is something odd on DynamicDocument, I changed Products inherit Document.
class EmbeddedDescriptionsReference(Document):
long_desc = StringField()
short_desc = StringField()
class Products(Document):
descriptions = ReferenceField(EmbeddedDescriptionsReference)
class ProductSerializer(MongoEngineModelSerializer):
class Meta:
model = Products
depth = 1
related_model_validations = {'descriptions': EmbeddedDescriptionsReference}
The key point to understand at mongoengine serializer is, to save foreign keys to collections -as object id- and fetch them as documents.
When you save Products, it looks like that on DB
{
"_id" : ObjectId("536a3c6d571a6506e110837c"),
"descriptions" : ObjectId("536a3bff571a6506e110837b"),
"some_other_field":"the value"
}
So, when querying, you should write the line like this:
product = Products.objects.get(pk=the_pk)
Use object IDs to query, not the whole Document.
Im guessing you are using the whole document to query, thats why you get that exception
The limitations are:
- You cant use EmbeddedDocument inside some other Document without ReferenceFields
- You should save your
EmbeddedDescriptionsReference
before saving yourProduct
I'm pretty busy nowadays, but I will make some enhancements to mongoengine serializer and develop a 3rd party what uses all features of mongoengine, starting EmbeddedDocuments first
from django-rest-framework-mongoengine.
Thanks. I'm querying the products collection by the primary key or some other string/int field. The error is a result of the descriptions field being a sub-document in the database, rather than an ObjectId. I don't have control over the document structure so I can't change the descriptions field to an ObjectId that references a different collection.
Even if I could, I wouldn't want to change it, since MongoDB is designed to embed sub-documents rather than reference other collections. Ideally, I would get the results in one query per HTTP GET. When referencing other collections, the client application must make a separate query for each reference and this can degrade performance. If an application must treat each document as a flat document and only using references for sub-documents, it would be better off using a relational database so that joins can be done within the database.
I will take a look when I have some free time. I think adding additional logic in to_native() in MongoEngineModelSerializer may work. Also, I don't think the depth should apply to embedded documents. Any thoughts on that?
from django-rest-framework-mongoengine.
If I can manage to serialize EmbeddedDocument
without treating it as a Document
(like a seperate Document as you mentioned), depth will not be necessary for the serializer anyway. The only reason I'm using depth is to make decision whether embed or reference the Document. And with ListField
support, MongoEngineModelSerializer would be a nice 3rd party.
For now, behaviour like ListField
is supported via custom SerializerMethodField
Finally, adding logic in to_native() may work with some built-in django model field extensions
from django-rest-framework-mongoengine.
@mkhndrsn ,
Check out embedded_document_serializing branch and let me know if it works for EmbeddedDocuments. It looks OK to me.
Any thoughts on further development (of serializing EmbeddedObjects)?
from django-rest-framework-mongoengine.
Ok, thanks. I'll take a look. Right now I'm thinking maybe requiring a a serializer for each embedded document type and then adding that serializer as a field similar to this:
class CommentSerializer(serializers.Serializer):
user = UserSerializer()
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
My current project is just finishing up so I should have some time next week or the week after to look into this further
from django-rest-framework-mongoengine.
Ok nice, I'll try nested serializers asap
from django-rest-framework-mongoengine.
Am I correct, that there is no way that Serializer would work with this model?
EmbeddedDocument -> ListField(EmbeddedDocumentField())
class Comment(EmbeddedDocument):
content = StringField()
name = StringField(max_length=120)
class Post(Document):
title = StringField(max_length=120, required=True)
author = ReferenceField(User)
tags = ListField(StringField(max_length=30))
comments = ListField(EmbeddedDocumentField(Comment))
Thanks a lot
from django-rest-framework-mongoengine.
I am working on it, take a look at list field branch and embedded document branch, it is possible
from django-rest-framework-mongoengine.
Cheers!
I've already checked out both branches before asking. Based on your judgement, how far it is from implantation? I mean, should I go through the code and try my best to get it done by myself. Is it the whole new code refactoring, or just fixing/adding some methods/parameters?
Thank you
from django-rest-framework-mongoengine.
Its just adding some methods, of course you can do it by yourself.
But the list field branch is not truly complete, yet.
I would appreciate any contribution though. I'll try to finalize and merge branches asap
from django-rest-framework-mongoengine.
Thank you
from django-rest-framework-mongoengine.
@zzzuzik check out latest commit
from django-rest-framework-mongoengine.
@umutbozkurt wow! really appreciate such a fast reaction. Thanks a million!
I had to replace unicode
with str
to make it work in Py3;
otherwise, NameError at <> name 'unicode' is not defined
I am going to keep using your latest code, so in case of any surprising findings I will report.
And thanks again for your efforts
from django-rest-framework-mongoengine.
Related Issues (20)
- Compatible with Django 3.0 HOT 3
- Embedded Document field has no attribute items error in recursive_save
- type object 'XXX' has no attribute '_fields' HOT 2
- Testing API's?
- rest_framework_mongoengine CreateOnlyDefault() not working
- NullBooleanField is deprecated in favor of BooleanField(allow_null=True)
- Serializer Field: `default=0` gets ignored HOT 1
- Let's use ref_name for nested embedded fields as well HOT 5
- The DocumentSerializer uses the default value from the model definition when the field does not even exists in the document yet HOT 2
- Is there a way to speed serializer? HOT 1
- No validation for primary key HOT 1
- `style` not included in `utils.get_field_kwargs()`; not aligned to DRF core arguments HOT 2
- Is nested DynamicEmbeddedDocument of Mongoengine supported in DRF mongoengine? HOT 2
- Is it possible to enable cache? HOT 3
- Create a Permissions Profile HOT 1
- Upon deserializing, reference fields are not present within the validated_data HOT 1
- QuerySet class in MongoEngine does not have .model key as the django.db.models.query.QuerySet.model in
- How using write_concern args when perform_create method is invoke
- Object of type ObjectId is not JSON serializable HOT 2
- AttributeError: module 'rest_framework.fields' has no attribute 'NullBooleanField' HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from django-rest-framework-mongoengine.