0

I have looked at a lot of articles about mutations with foreign keys and nothing is helping.

I need to create a person with a django model Person, that has an address that is a foreign key to the Address model. A person needs an address!

My models in django are:

from django.db import models


class Address(models.Model):
    class Meta:
        verbose_name_plural = "Addresses"

    number = models.CharField(max_length=4)
    street = models.CharField(max_length=100)
    city = models.CharField(max_length=100)
    postcode = models.CharField(max_length=7)


class Person(models.Model):
    class Meta:
        verbose_name_plural = "Persons"

    avatar = models.ImageField(upload_to='images/avatars/')
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    address = models.ForeignKey(Address, on_delete=models.CASCADE)
    personal_image = models.ImageField(upload_to='images/personal_images/')

    def get_fullname(self):
        return self.first_name + ' ' + self.last_name

My mutations in my schema are:

class AddressInput(graphene.InputObjectType):
    number = graphene.String(required=True)
    street = graphene.String(required=True)
    city = graphene.String(required=True)
    postcode = graphene.String(required=True)


class CreatePerson(graphene.Mutation):
    class Arguments:
        avtr = Upload(required=False)
        fname = graphene.String(required=True)
        lname = graphene.String(required=True)
        addr = graphene.Argument(AddressInput, required=False)
        pimage = Upload(required=False)


    person = graphene.Field(PersonType)

    def mutate(self, info, avtr, fname, lname, addr, pimage):
        person = Person(
            avatar=avtr,
            firstName=fname,
            lastName=lname,
            address=addr,
            personalImage=pimage
        )
        return CreatePerson(person=person)

class Mutations(graphene.ObjectType):
    create_person = CreatePerson.Field()

I am testing with GraphiQL and my mutation atm looks like this:

mutation createPerson {
  createPerson(avtr: None, fname: "Bob", lname: "Diamond", addr: {number: "10", street: "Hormond Avenue", city: "Shrewsbury", postcode: "N7 9RF"}, pimage: None) {
    person {
      firstName
      lastName
    }
  }
}

Output I get is:

{
  "errors": [
    {
      "message": "Cannot assign \"{'number': '10', 'street': 'Hormond Avenue', 'city': 'Shrewsbury', 'postcode': 'N7 9RF'}\": \"Person.address\" must be a \"Address\" instance.",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "createPerson"
      ]
    }
  ],
  "data": {
    "createPerson": null
  }
}
Davtho1983
  • 3,827
  • 8
  • 54
  • 105

1 Answers1

0

Is a person supposed to be only one address, or is the relationship Many Addresses to One Person?


I believe that you need to create the GraphQL types, not just the mutations. For example:

class PersonNode(DjangoObjectType):
    address = graphene.Field(AddressObjectType)

    class Meta:
        model = Person

    def resolve_address(self, info):
        address = self.person.address
        return AddressObjectType(
          id=address.id,
          street=address.street,
          zip=address.zip
        )

class AddressNode(DjangoObjectType):
    id = graphene.ID()
    street = graphene.String()
    zip = graphene.Int()
Sebastian Scholl
  • 855
  • 7
  • 11
  • Only one address per person at this stage. The wider issue tho is that mutations don't seem to work at all - completely stumped with graphene 2.0 – Davtho1983 Oct 10 '19 at 15:11