簡體   English   中英

具有多對多和直通表的 Graphene-django

[英]Graphene-django with ManyToMany & through-table

我的應用程序與直通模型有幾個多對多關系如下所示:

class Person(models.Model):
    name = models.CharField()

class Group(models.Model):
    name = models.CharField()
    members = models.ManyToManyField(Person, through='Membership')

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    date_joined = models.DateField()  # Extra info on the relationship

在 graphql 中表示這些數據而沒有成員資格的中間類型(選項 A)似乎很直觀:

{
  "data": {
    "persons": [
      {
        "id": "1",
        "name": "Jack",
        "groups": [
          {
            "id": 3,                     # From Group-model
            "name": "Students",          # From Group-model
            "date_joined": "2019-01-01"  # From Membership-model
          },
          ...
        ]
      }
    ]
  }
}

對比選項 B:

{
  "data": {
    "persons": [
      {
        "id": "1",
        "name": "Jack",
        "memberships": [
          {
            "id": 9,
            "date_joined": "2019-01-01"
            "group": {
              "id": 3, 
              "name": "Students"
            }
          },
          ...
        ]
      }
    ]
  }
}

我找不到任何關於如何使用 (django-)graphene 實現選項 A 的示例。 如何做到這一點,是否支持開箱即用?

兩種方法的優缺點是什么? 數據也需要經常變異,它會改變判決嗎?

您可以通過創建一個表示來自兩個模型的字段的類型來實現這一點。 例如:

import graphene
from graphene_django.types import DjangoObjectType


# hybrid type, expresses some characteristics of Member and Group
class UserGroupType(DjangoObjectType):
    class Meta:
        model = Membership
    
        # date_joined is automatically derived from the membership
        # instance, name and id are declared below.
        fields = ('id', 'name', 'date_joined', )
    
    id = graphene.ID()
    name = graphene.String()
    
    def resolve_id(value_obj, info):
        return value_obj.group.pk

    def resolve_name(value_obj, info):
        return value_obj.group.name


class PersonType(DjangoObjectType):
    class Meta:
        model = Person
    
        # id and name are automatically derived from the person
        # instance, groups is declared below, overriding the 
        # normal model relationship.
        fields = ('id', 'name', 'groups', )
    
    groups = graphene.List(UserGroupType)
    
    def resolve_groups(value_obj, info):
        return value_obj.memberships

對於從 Graphene 的ObjectType (它是DjangoObjectType 的后代)構建的任何類型,要在輸出中表達一個字段,您需要做兩件事:

  1. 字段類型的聲明
  2. 生成要轉換為該類型的結果的解析器方法

DjangoObjectType評估您提供的模型以自動生成這些模型,並使用fields 屬性讓您自定義要顯示的屬性。

通過自定義fields ,然后為要添加的內容添加手動道具/解析器,您可以使類型返回您想要的任何內容。

請注意,解析器不會接收self作為第一個參數,而是獲取值 object 值對象是查詢解析器的返回值,通常是模型的實例或與過濾器匹配的模型數組等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM