strawberry-django icon indicating copy to clipboard operation
strawberry-django copied to clipboard

Defining related fields on an interface throws a type mismatch error

Open fireteam99 opened this issue 1 year ago • 1 comments

Describe the Bug

When defining an interface with that contains any related field, an error is thrown where the type is identified to be a DjangoModelType but is (correctly) a Strawberry type.

In the example below, we are passing in CardNode (a strawberry type) as the related field, but error thinks it is a DjangoModelType.

Code:

@strawberry.interface
class MyInterface(MyBaseClass):
  card: "CardNode"

@strawberry.django.type(Card)
class CardNode:
  name: auto

Error:

❌ Interface field MyInterface.card expects type CardNode! but MyInterface.card is type DjangoModelType.```
## System Information

 - Operating system: macOS
 - Strawberry version (if applicable): 0.133.5
 - Strawberry Django version: 0.5.3

## Additional Context
Strawberry discord thread: https://discordapp.com/channels/689806334337482765/1029471127963172894

fireteam99 avatar Oct 11 '22 20:10 fireteam99

Hi @fireteam99 ,

Is MyBaseClass your django base model?

What I usually do is to have an abstract model mixin and define an interface out of it with a code like this:

class SomeModelMixin(models.Model):
    class Meta:
        abstract = True

    some_field = models.CharField(...)


@strawberry.django.type(is_interface=True)
class SomeModelInterface:
    some_field: strawberry.auto


@strawberry.django.type(ConcreteModel)
class ConcreteModelType(SomeModelInterface):
    ...

I'm using strawberry-django-plus's @interface for that, which is basically a shortcut. I don't remember if I had any special handling for it, so if the example above doesn't work we can probably try to port the code that handles it to this repo :)

bellini666 avatar Oct 13 '22 13:10 bellini666

Hi @bellini666, MyBaseClass is a django graphene type that maps to a django base model. The MyInterface interface I am try to create maps to an abstract django model which inherits from the MyBaseClass model.

I tried your suggestion with the is_interface arg but got a different error:

@strawberry.interface
class MyInterface(AbstractDjangoModel, is_interface=True):
  card: "CardNode"

@strawberry.django.type(Card)
class CardNode:
  name: auto

Error:

AttributeError: 'NoneType' object has no attribute 'expandtabs'

fireteam99 avatar Oct 18 '22 04:10 fireteam99

@fireteam99 actually you should write that like this:

@strawberry.django.type(AbstractDjangoModel, is_interface=True)
class MyInterface:
  card: "CardNode"

@strawberry.django.type(Card)
class CardNode:
  name: auto

bellini666 avatar Oct 18 '22 15:10 bellini666

Hmmm so when I tried @strawberry.django.type(is_interface=True) it complained: TypeError: type() missing 1 required positional argument: 'model'

But when I tried to pass my abstract Django model as the type @strawberry.django.type(MyAbstractModel, is_interface=True) I got the expandtabs error again:

AttributeError: 'NoneType' object has no attribute 'expandtabs'

fireteam99 avatar Oct 24 '22 19:10 fireteam99

@fireteam99 sorry, in a hurry I wrote it wrong. The model should be passed as the first argument to the strawberry.django.type function. I edited my response with the correct solution

bellini666 avatar Oct 26 '22 16:10 bellini666

@bellini666 ah gotcha. I tried that but I'm still getting the expandtabs error...

fireteam99 avatar Oct 27 '22 19:10 fireteam99