eamigo86 / graphene-django-extras

Extras functionalities for Graphene-Django
MIT License
415 stars 104 forks source link

Complete Many to Many With and Without "Through" Table Example #141

Open IdemenB opened 4 years ago

IdemenB commented 4 years ago

Dear @eamigo86 , thanks a lot for this library. I only whish the documentation was a bit more detailed and surprisingly I wasn't able to find a single proper tutorial on any platform using this great library of yours for Graphene and Django.

What I need is a complete example of how to query and mutate models with M2M relations that have a through table or not. .

Example models:

class Person(models.Model):
    name = models.CharField(max_length=100, blank=False)

class Booking(models.Model):
    people = models.ManyToManyField(Person, related_name="bookings", blank=False)

Using this library, especially DjangoListObjectField and DjangoSerializerMutation how can I do the following. Answers to these would be such a valuable addition into the documentation for beginners like me:

1) Query all Person instances and their respective Bookings 2) Create a person and while creating the person, link ito an already existing Booking instance 3) Create a person and while creating the person, create also a Booking instance and link the two.

I believe for the 3rd one, we will need to run two instance creations seperately and then use instancefield.add or .set methods for the linking, however, I can't figure out what to userwrite, should it be the Serializer's create method or something in the Mutation?

Thanks to everyone contributing here!

IdemenB commented 4 years ago

Is someone has experience with the item 2, that is, creating a model instance and relating it with an already existing M2M model instance, her help would be much appreciated indeed...

IdemenB commented 4 years ago

Trying to ready every single post on M2M relations and serializers I've found the solution for ITEM 2 thanks to this on SO: [(https://stackoverflow.com/questions/39391423/django-rest-framework-not-saving-reference-to-many-to-many)]

It is very interesting that if we want to make a M2M relation with an already existing instance of the related model, the serializer has to be defined as "vanilla" ModelSerializer, without explicitly defining the related field and its Serializer. So this is all needed:

Note: country field on User model has M2M relation with Country model. Serializer:

`class UserSerializer(serializers.ModelSerializer):

# SHOULD BE REMOVED !!!!! 
# country = CountrySerializer(many=True, read_only=True)

class Meta:
    model = User
    fields = '__all__'`

Serializer:

class UserSerializerMutation(DjangoSerializerMutation):

   # SHOULD BE REMOVED !!!!! 
   #country = DjangoListObjectField(CountryListType)

    class Meta:
        description = "DRF serializer based Mutation for Users"
        serializer_class = UserSerializer

And sample mutation query:

mutation{
  userCreate(
    newUserData:{

      firstName:"abc", 
      lastName:"dsfresdfds", 
      personType:A_1, 
      email:"nfgdgfddsfdff@xxxx.com", 
      password:"tdest*123",
      country: ["35", "65"]  --> pass M2M instances' primary keys as an Array

      }
      )

  {

    user{
      id
      firstName
      lastName

      country {
              name
      }

    }
    ok
    errors{
      field
    messages}

  }}