Skip to content

Commit 0f93fb9

Browse files
authored
Merge pull request #13 from graphql-python/feat-list-of-embedded-document
Feature: Support ListField(EmbeddedDocumentField)
2 parents 7811e49 + 247e149 commit 0f93fb9

File tree

9 files changed

+473
-370
lines changed

9 files changed

+473
-370
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,12 @@ To learn more check out the following [examples](examples/):
7373
- [x] Flask example
7474
- [ ] Django example
7575
- [ ] Filtering & Paging
76-
- [x] Default filtering enabled with all model's attributes by equal comparison
77-
- [x] Take first, or last n items
76+
- [x] Default filtering enabled with all model's attributes by equal comparison (requester: [git-albertomarin](https://github.com/git-albertomarin))
77+
- [x] Take first, or last n items (credit: [alexpantyukhin](https://github.com/alexpantyukhin))
7878
- [ ] Advanced filtering
7979
- [ ] Support more types
80-
- [x] Self-reference and list-of-self-reference relationship
81-
- [ ] List(EmbeddedDocument)
80+
- [x] Self-reference and list-of-self-reference relationship (requester: [mehdiym](https://github.com/mehdiym))
81+
- [x] ListField(EmbeddedDocumentField)
8282
- [ ] Others
8383

8484
## Contributing

graphene_mongo/converter.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,22 @@ def convert_date_to_string(field, registry=None):
6060
@convert_mongoengine_field.register(mongoengine.ListField)
6161
def convert_field_to_list(field, registry=None):
6262
base_type = convert_mongoengine_field(field.field, registry=registry)
63+
6364
if isinstance(base_type, (Dynamic)):
64-
base_type = base_type.get_type()._type
65+
base_type = base_type.get_type()
66+
if base_type is None:
67+
return
68+
base_type = base_type._type
69+
6570
if is_node(base_type):
6671
return MongoengineConnectionField(base_type)
67-
elif not isinstance(base_type, (List, NonNull)) \
68-
and not isinstance(field.field, mongoengine.ReferenceField):
72+
73+
# Non-relationship field
74+
relations = (mongoengine.ReferenceField, mongoengine.EmbeddedDocumentField)
75+
if not isinstance(base_type, (List, NonNull)) \
76+
and not isinstance(field.field, relations):
6977
base_type = type(base_type)
78+
7079
return List(base_type, description=field.db_field, required=not field.null)
7180

7281

graphene_mongo/tests/fixtures.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from .models import Article, Editor, EmbeddedArticle, Player, Reporter
2+
3+
4+
def setup_fixtures():
5+
Editor.drop_collection()
6+
editor1 = Editor(first_name='Penny', last_name='Hardaway')
7+
editor1.save()
8+
editor2 = Editor(first_name='Grant', last_name='Hill')
9+
editor2.save()
10+
editor3 = Editor(first_name='Dennis', last_name='Rodman')
11+
editor3.save()
12+
13+
Article.drop_collection()
14+
article1 = Article(headline='Hello', editor=editor1)
15+
article1.save()
16+
article2 = Article(headline='World', editor=editor2)
17+
article2.save()
18+
19+
Reporter.drop_collection()
20+
reporter = Reporter(first_name='Allen', last_name='Iverson',
21+
email='[email protected]', awards=['2010-mvp'])
22+
reporter.articles = [article1, article2]
23+
embedded_article1 = EmbeddedArticle(
24+
headline='Real',
25+
editor=editor1
26+
)
27+
embedded_article2 = EmbeddedArticle(
28+
headline='World',
29+
editor=editor2
30+
)
31+
reporter.embedded_articles = [embedded_article1, embedded_article2]
32+
reporter.save()
33+
34+
Player.drop_collection()
35+
player1 = Player(first_name='Michael', last_name='Jordan')
36+
player1.save()
37+
player2 = Player(first_name='Magic', last_name='Johnson', opponent=player1)
38+
player2.save()
39+
player3 = Player(first_name='Larry', last_name='Bird', players=[player1, player2])
40+
player3.save()
41+
42+
player1.players = [player2]
43+
player1.save()
44+
45+
player2.players = [player1]
46+
player2.save()

graphene_mongo/tests/models.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ class Reporter(Document):
4949
last_name = StringField(required=True)
5050
email = EmailField()
5151
articles = ListField(ReferenceField(Article))
52-
# FIXME
53-
# embedded_articles = ListField(EmbeddedDocumentField(EmbeddedArticle))
52+
embedded_articles = ListField(EmbeddedDocumentField(EmbeddedArticle))
5453
# FIXME
5554
# custom_map = MapField(field=StringField())
5655
awards = ListField(StringField())

graphene_mongo/tests/test_converter.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def test_should_field_convert_list():
7575
assert_conversion(mongoengine.ListField, graphene.List, field=mongoengine.StringField())
7676

7777

78-
def test_should_reference_convert_dynamic():
78+
def test_should_embedded_convert_dynamic():
7979

8080
class E(MongoengineObjectType):
8181

@@ -90,7 +90,7 @@ class Meta:
9090
assert graphene_type.type == E
9191

9292

93-
def test_should_one2many_convert_list():
93+
def test_should_list_of_reference_convert_list():
9494

9595
class A(MongoengineObjectType):
9696

@@ -102,8 +102,21 @@ class Meta:
102102
dynamic_field = graphene_field.get_type()
103103
assert dynamic_field._of_type == A
104104

105+
106+
def test_should_list_of_embedded_convert_list():
107+
108+
class E(MongoengineObjectType):
109+
110+
class Meta:
111+
model = EmbeddedArticle
112+
113+
graphene_field = convert_mongoengine_field(Reporter._fields['embedded_articles'], E._meta.registry)
114+
assert isinstance(graphene_field, graphene.List)
115+
dynamic_field = graphene_field.get_type()
116+
assert dynamic_field._of_type == E
117+
118+
105119
def test_should_self_reference_convert_dynamic():
106-
# pass
107120
class P(MongoengineObjectType):
108121

109122
class Meta:

0 commit comments

Comments
 (0)