torchbox / wagtail-grapple

A Wagtail app that makes building GraphQL endpoints a breeze!
https://wagtail-grapple.readthedocs.io/en/latest/
Other
152 stars 57 forks source link

Exception: model attribute exists but is not a field #45

Closed indirectlylit closed 4 years ago

indirectlylit commented 4 years ago

I'm not exactly sure how what happened because I don't recall seeing this behavior previously.

I have a model like this:

class BlogIndexPage(Page):
    intro = RichTextField(blank=True)
    content_panels = Page.content_panels + [FieldPanel("intro", classname="full")]

    @property
    def blogpages(self):
        return self.get_children().live().order_by("-first_published_at")

    graphql_fields = [GraphQLString("intro")]

which gives me an error like:

Traceback (most recent call last):
  File "python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "django/utils/autoreload.py", line 54, in wrapper
    fn(*args, **kwargs)
  File "django/core/management/commands/runserver.py", line 109, in inner_run
    autoreload.raise_last_exception()
  File "django/utils/autoreload.py", line 77, in raise_last_exception
    raise _exception[1]
  File "django/core/management/__init__.py", line 337, in execute
    autoreload.check_errors(django.setup)()
  File "django/utils/autoreload.py", line 54, in wrapper
    fn(*args, **kwargs)
  File "django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "django/apps/registry.py", line 122, in populate
    app_config.ready()
  File "grapple/apps.py", line 16, in ready
    load_type_fields()
  File "grapple/actions.py", line 263, in load_type_fields
    node = type(type_name, (base_type,), type_meta)
  File "graphene/utils/subclass_with_meta.py", line 52, in __init_subclass__
    super_class.__init_subclass_with_meta__(**options)
  File "graphene_django/types.py", line 177, in __init_subclass_with_meta__
    construct_fields(model, registry, fields, exclude, convert_choices_to_enum),
  File "graphene_django/types.py", line 46, in construct_fields
    raise Exception(
Exception: "approved_schedule" exists on model <class 'blog.models.BlogIndexPage'> but it's not a field.

I am currently working around this by manually including all properties of a wagtail Page, but that doesn't seem quite correct based on the documentation:

page_fields = [
    GraphQLString(f)
    for f in [
        "page_ptr",
        "approved_schedule",
        "blogpages",
        "default_preview_mode",
        "full_url",
        "pk",
        "preview_modes",
        "status_string",
        "url",
    ]
]

class BlogIndexPage(Page):
    intro = RichTextField(blank=True)
    content_panels = Page.content_panels + [FieldPanel("intro", classname="full")]

    @property
    def blogpages(self):
        return self.get_children().live().order_by("-first_published_at")

    graphql_fields = page_fields + [GraphQLString("intro")]

Versions:

Django==2.2.9
graphene==2.1.8
graphene-django==2.8.0
graphql-core==2.2.1
wagtail==2.7.1
wagtail-grapple==0.4.8
NathHorrigan commented 4 years ago

Hi @indirectlylit,

This is an issue caused by how graphen-django handles excluded fields for model types that got released as a feature release. If you update to the latest grapple version it should lock your version of graphene-django to before the new release. We are working on a better fix for this.

To be specific you need:

wagtail-grapple==0.4.10
graphene-django==2.7.1

Thanks for the feedback, Nathan

indirectlylit commented 4 years ago

thank you