1

注:これは実際に余分なフィールドを持つ多対多の関係のDjangoの中間モデルを取得することではありません。これはDjango Rest FrameworkのSerializers.ModelSerializerを中間モデルで使用する方法です。 は、私はこれらのモデル(およびそれ以上)があります。多対多モデル(余分なデータを含む)を持つdjango drfシリアライザ

class Method(models.Model): 
    name = models.CharField(max_length=50, unique=True) 
    descripton = models.TextField(null=False) 

class Version(models.Model): 
    version_number = models.CharField(max_length=50) 
    cmd_line_script = models.CharField(max_length=250, null=False) 
    SOP = models.TextField(null=False) 
    FK_method = models.ForeignKey(Method, on_delete=models.CASCADE) 

    class Meta: 
     unique_together = ('version_number', 'FK_method') 

class Instrument(models.Model): 
    serial_number = models.CharField(max_length=50, unique=True) 
    asset_number = models.CharField(max_length=50, unique=True) 
    name = models.CharField(max_length=50) 
    checksum_string = models.CharField(max_length=128, null=True) 
    FK_instr_type = models.ForeignKey(InstrType, related_name='installations', on_delete=models.PROTECT) 
    Instr_Version = models.ManyToManyField(
         Version, 
         through='Instr_Version', 
         related_name = 'Instr_Version', 
        ) 

class Instr_Version(models.Model): 
    FK_version = models.ForeignKey(Version, on_delete=models.CASCADE) 
    FK_instrument = models.ForeignKey(Instrument, on_delete=models.CASCADE) 
    validating_user = models.ForeignKey(UserProfile, on_delete=models.PROTECT) 
    timestamp = models.DateField(auto_now_add=True) 

    class Meta: 
     unique_together = ('FK_version', 'FK_instrument') 

を、彼らはいいですよ。私は[Django-Rest-Framework serializers][1]をInstr_Versionテーブルを介してシリアル化するようにしています。そのため、apiは、その計測器で有効なものとしてリストされているすべてのバージョン(MethodSerializerを介してFK_methodデータ)のjson表現を取得できます。 私はこれまでのところ、これらのシリアライザを持っている(とInstrType、のUserProfileなどのためのカップルより)

class MethodSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Method 
     fields = ('id', 'name', 'description', 'version_set') 

class VersionSerializer(serializers.ModelSerializer): 
    method = MethodSerializer(read_only=True) 
    #Instr_Version = Instr_VersionSerializer(source='Instr_Version_set', many=True, read_only=True) 
    class Meta: 
     model = Version 
     fields = ('id', 'method', 'version_number', 'cmd_line_script', 'SOP') 

class Instr_to_VersionSerializer(serializers.ModelSerializer): 
    version = VersionSerializer(source='FK_version_id', read_only=True, many=False) 
    validator = UserProfileSerializer(source='validating_user', read_only=True) 

    class Meta: 
     model = Instr_Version 
     fields = ('id', 'version', 'validator', 'timestamp') 


class InstrumentSerializer(serializers.ModelSerializer): 
    instr_type = InstrTypeSerializer(source='FK_instr_type', read_only=True) 
    Validated_Versions = Instr_to_VersionSerializer(source='Instr_Version', many=True, read_only=True) 

    class Meta: 
     model = Instrument 
     fields = ('id', 'asset_number', 'serial_number', 'name', 'checksum_string', 'instr_type', 'Validated_Versions') 

私が得ている最も近いですそのようなGET: "API/getInstrument/asset_number = 1234?" 結果in:

{ 
    "id": 11, 
    "asset_number": "1234", 
    "serial_number": "1234", 
    "name": "Instrument1", 
    "checksum_string": "ABCDEF0123", 
    "instr_type": { 
     "id": 70, 
     "make": "Make1", 
     "model": "Model1", 
     "service_email": "[email protected]", 
     "service_website": "www.model1.com" 
    }, 
    "Validated_Versions": [{ 
     "id": 9 
    }, { 
     "id": 10 
    }, { 
     "id": 12 
    }] 
} 

これはかなり良いですが、validated_versions配列には単に「id」以外のデータが必要です。

Instr_to_VersionSerializerVersionSerializerのフィールドリストからidを追加/削除しようとしました。実際にInstr_to_VersionSerializerのフィールドリストのidInstr_VersionInstr_VersionというモデルではなくInstr_Versionモデル(またはバージョンモデルのPK)のFK_version_idを実際に印刷しています。これは私がまっすぐVersionモデルに、DJRは「自動的に」多対多を通して見ていたことを考えさせられましたので、私はにInstr_to_VersionSerializerを変えてみました:

完全にそれのうちVersionSerializerを残すだろう
class Instr_to_VersionSerializer(serializers.ModelSerializer): 
    #version = VersionSerializer(source='FK_version_id', read_only=True, many=False) 
    validator = UserProfileSerializer(source='validating_user', read_only=True) 
    #method = MethodSerializer(read_only=True) 

    class Meta: 
     model = Instr_Version 
     fields = ('id', 'version_number', 'cmd_line_script', 'SOP', 'validator', 'timestamp') 

が、私はField name version_number is not valid for model Instr_Version .というエラーが発生するので、何が起こっているのか分かりません。

最後に、version = VersionSerializersourceversionsに変更しました。逆の関係です。これは非合理に思えましたが、私は何かを試しているところです。結果は:version_numberは有効なフィールドではなく、最終的にVersionSerializerになっていたので、私はVersionSerializerのフィールドのほとんどをコメントアウトしましたが、何が起こっているのかを見てみましょう。 "Validated_Versions":[{"id":9,"version":{}},{"id":10,"version":{}},{"id":12,"version":{}}]

答えて

0

InstrumentsInstr_Versionの関係が原因で問題が発生していたのは、related_nameでした。私はにモデルを更新:

class Instrument(models.Model): 
    serial_number = models.CharField(max_length=50, unique=True) 
    asset_number = models.CharField(max_length=50, unique=True) 
    name = models.CharField(max_length=50) 
    checksum_string = models.CharField(max_length=128, null=True) 
    FK_instr_type = models.ForeignKey(InstrType, related_name='installations', on_delete=models.PROTECT) 
    VersionsFromInstrument = models.ManyToManyField(
         Version, 
         through='Instr_Version', 
         related_name = 'InstrumentsFromVersion', 
        ) 

(最後の属性に新しいrelated_nameに注意してください、と私は属性名を変更している)、およびシリアライザはそれに応じて、これは良く働いています。 note makemigrationsmigratemanage.pyで更新したところ、このモデルは更新されました。新しい結果は次のとおりです。

{ 
    "id": 11, 
    "asset_number": "1234", 
    "serial_number": "1234", 
    "name": "Instrument1", 
    "checksum_string": "ABCDEF0123", 
    "instr_type": { 
     "id": 70, 
     "make": "Make1", 
     "model": "Model1", 
     "service_email": "[email protected]", 
     "service_website": "www.model1.com" 
    }, 
    "Validated_Versions": [{ 
     "id": 9, 
     "method": { 
      "id": 9, 
      "name": "Method1", 
      "description": "method one description", 
      "version_set": [11, 9] 
     }, 
     "version_name": "123", 
     "cmd_line_script": "script", 
     "SOP": "SOP" 
    }, { 
     "id": 10, 
     "method": { 
      "id": 10, 
      "name": "Method2", 
      "description": "method two description", 
      "version_set": [12, 10] 
     }, 
     "version_name": "123", 
     "cmd_line_script": "script", 
     "SOP": "SOP" 
    }, { 
     "id": 12, 
     "method": { 
      "id": 10, 
      "name": "Method2", 
      "description": "method two description", 
      "version_set": [12, 10] 
     }, 
     "version_name": "456", 
     "cmd_line_script": "script", 
     "SOP": "SOP" 
    }] 
} 

場合にはそれがこちらのモデルへの変更と相関するために私の更新Serilaizersだ、将来的に他の人に役立ちます:

class MethodSerializer(serializers.ModelSerializer): 
    description = serializers.ReadOnlyField(source='descripton') 
    class Meta: 
     model = Method 
     fields = ('id', 'name', 'description', 'version_set') 

class VersionSerializer(serializers.ModelSerializer): 
    method = MethodSerializer(read_only=True) 
    #Instr_Version = Instr_VersionSerializer(source='Instr_Version_set', many=True, read_only=True) 
    class Meta: 
     model = Version 
     fields = ('id', 'method')#, 'version_number', 'cmd_line_script', 'SOP') 

class Instr_to_VersionSerializer(serializers.ModelSerializer): 
    version = VersionSerializer(source='FK_version', read_only=True, many=True) 
    validator = UserProfileSerializer(source='validating_user', read_only=True) 
    version_name = serializers.ReadOnlyField(source='version_number') 
    cmd_line_script = serializers.ReadOnlyField() 
    SOP = serializers.ReadOnlyField() 
    method = MethodSerializer(source='FK_method',read_only=True) 

    class Meta: 
     model = Instr_Version 
     fields = ('id', 'version', 'validator', 'timestamp', 'method', 'version_name', 'cmd_line_script', 'SOP') 


class InstrumentSerializer(serializers.ModelSerializer): 
    instr_type = InstrTypeSerializer(source='FK_instr_type', read_only=True) 
    Validated_Versions = Instr_to_VersionSerializer(source='VersionsFromInstrument', many=True, read_only=True) 

    class Meta: 
     model = Instrument 
     fields = ('id', 'asset_number', 'serial_number', 'name', 'checksum_string', 'instr_type', 'Validated_Versions') 

特にInstrumentSerializer

Validated_Versions =ラインに注意してください

私が見逃していることは、実際には結果としてInstr_Versionモデルのvalidating_usertimestampのフィールドが見たいということです。そのためにはまだ作業が必要です。私はそれが働くようになると私は更新されます。

関連する問題