2016-02-22 19 views
6

私はDjangoとDjango-RESTの新機能ですので、私にご負担ください。おそらく答えはドキュメントにありますので、私がそれを逃した場合は、事前にお詫び申し上げます。Django REST - シリアライザを使用して外部キーを持つオブジェクトを作成する

目標:属性に既存の外部キー(EquipmentTypeとEquipmentManufacturer)が含まれているEquipmentInfoオブジェクトを作成したいとします。

models.py

class EquipmentType(models.Model): 
    equipment_type = models.CharField(verbose_name="Equipment Type", max_length=50, unique=True) 

    def __unicode__(self): 
     return self.equipment_type 


class EquipmentManufacturer(models.Model): 

    manufacturer_name = models.CharField(verbose_name="Manufacturer Name", max_length=50, unique=True) 

    def __unicode__(self): 
     return self.manufacturer_name 


class EquipmentInfo(models.Model): 

    equipment_type = models.ForeignKey(EquipmentType, verbose_name="Equipment Type") 
    part_identifier = models.CharField(verbose_name="Machine ID (alias)", max_length=25) 
    manufacturer_name = models.ForeignKey(EquipmentManufacturer, verbose_name="Manufacturer Name") 
    serial_number = models.CharField(verbose_name="Serial Number", max_length=25) 
    date_of_manufacture = models.DateField(verbose_name="Date of Manufacture", default=date.today) 
    is_active = models.BooleanField(verbose_name="Is Active", default=True) 

    def __unicode__(self): 
     return self.part_identifier 

serializers.py

class EquipmentTypeSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = EquipmentType 
     fields = ('id', 'equipment_type',) 

class EquipmentManufacturerSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = EquipmentManufacturer 
     fields = ('id', 'manufacturer_name',) 

class EquipmentInfoSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = EquipmentInfo 
     fields = ('id', 'equipment_type', 'part_identifier', 'manufacturer_name','serial_number', 'date_of_manufacture', 'is_active') 

    equipment_type = EquipmentTypeSerializer(many=False) 
    manufacturer_name = EquipmentManufacturerSerializer(many=False) 

    def create(self, validated_data): 
     equipment_type = validated_data.pop('equipment_type') 
     manufacturer_name = validated_data.pop('manufacturer_name') 
     equipment_info = EquipmentInfo.objects.create(**validated_data) 
     return equipment_info 

私はすでに作成され、関連するEquipmentTypeとEquipmentManufacturerオブジェクトを持っていると仮定すると、私は別のEquipmentInfoオブジェクトを追加したいと思います。

{ 
"equipment_type":"already_created", 
"part_identifier":"something_new", 
"manufacturer_name":"already_created", 
"serial_number":"WBA1", 
"date_of_manufacture": "1900-01-01", 
"is_active":true 
} 

すべてのヘルプは高く評価されています。私は、このような

{ 
"equipment_type":{ 
    "equipment_type":"already_created", 
}, 
"part_identifier":"something_new", 
"manufacturer_name":{ 
    "manufacturer_name":"already_created" 
}, 
"serial_number":"WBA1", 
"date_of_manufacture": "1900-01-01", 
"is_active":true 
} 

またはより良いなどの情報を渡すことができるように、何が私のEquipmentInfo・シリアライザを設定するための適切な方法です。

+0

あなたは明確にできますか? getを実行するときにネストされたシリアライザを取得できるようにするには問題がありますが、ポスティング時には既存のオブジェクトのレコードIDを渡したいだけですか? – dkarchmer

+0

ブラウズ可能なAPIを使用して新しい 'EquipmentInfo'レコードを投稿すると、 'equipment_type'と' manufacturer_name'が既に存在するというエラーが表示されます。私は既に 'EquipmentType'と' EquipmentManufacturer'レコードを持っているのでこれが期待されます。しかし今、私は新しい 'EquipmentInfo'レコードを追加したいと思います。つまり、ある意味では、既存のオブジェクトのレコードIDを渡したいだけです。理想的には、情報を送信するどのデバイスであれ、idフィールドの値を知る必要はなく、単に 'equipment_type'と' manufacturer_name'を使うことができます。それが明確になるのに役立つのでしょうか? – mcaro

答えて

1

ネストされたシリアライザを使用すると、ポスト(実際に動作していても動作しなかった場合)が難しくなります。シンプルなモデルがあれば、削除することをおすすめします。

私はあなたが

/api/v1/type 
/api/v1/manufacturer 
/api/v1/info 

(または任意の名前を使用する)ためのAPIを追加しますお勧めします。 typemanufacturerは、バニラ・ビューで、既存のシリアライザを使用する必要があります。あなたが使用してポストを行うことができる必要があり、その後

class EquipmentInfoSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = EquipmentInfo 
     fields = ('id', 'equipment_type', 'part_identifier', 'manufacturer_name','serial_number', 'date_of_manufacture', 'is_active') 

infoについては、ネストされた2つのシリアライザを削除私の場合は

data = { 
    "equipment_type": 5, # The ID of the equipment type record 
    "part_identifier":"something_new", 
    "manufacturer_name": 10 # The ID of the manufacturer record 
    "serial_number":"WBA1", 
    "date_of_manufacture": "1900-01-01", 
    "is_active":true 
} 

、私はそれGETを作る好きです私は読み取り専用のフィールドを追加して名前(またはシリアル化されたレコード全体)を返します。

class EquipmentInfoSerializer(serializers.ModelSerializer): 
    type_name = serializers.SerializerMethodField(read_only=True) 

    class Meta: 
     model = EquipmentInfo 
     fields = ('id', 'equipment_type', 'part_identifier', 'manufacturer_name','serial_number', 'date_of_manufacture', 'is_active') 

    def get_type_name(self, obj): 
     return obj.equipment_type.equipment_type 

これが役に立ちます。

0

は、私が問題にも直面している、そしてそれを解決した、次は私のステップであり、次のようにそれは便利 1.companyモデルと接触モデルであることを願っています:

class Company(models.Model): 
    Company_Name = models.CharField(u'Company Name',max_length=255, default="") 
    Modified_By = models.CharField(u'Modified By',max_length=255, default="") 



class Company_Contact(models.Model): 
    Company = models.ForeignKey(Company) 
    Last_Name = models.CharField(u'Last Name',max_length=255, default="") 
    First_Name = models.CharField(u'First Name',max_length=255, default="") 

2.Iを作成します新CompanyReferenceSerializer名前付きシリアライザ、およびcompany_contact

class CompanyReferenceSerializer(serializers.ModelSerializer): 
class Meta: 
    model = Company 
    fields = ['id', 'Company_Name', 'Company_Name_SC'] 





class CompanyContactSerializer(serializers.ModelSerializer): 
    Company = CompanyReferenceSerializer() 
class Meta: 
    model = Company_Contact 
    fields = ['Company', 'Last_Name','First_Name'] 
    extra_kwargs = { 
     'Company': {'allow_null': True, 'required': False}, 
     'Last_Name': {'allow_null': True, 'allow_blank': True, 'required': False}, 
     'First_Name': {'allow_null': True, 'required': False, 'allow_blank': True},  
    } 

3。次のようにビューセットは、バックエンドで、私は成功company_contactに1つのレコードを挿入

class CompanyContactViewSet(viewsets.ModelViewSet): 
    serializer_class = CompanyContactSerializer 
def create(self, validated_data): 
    serializer = self.get_serializer(data=self.request.data) 
    company_id_for_contact = self.request.data.pop('Company_id') 
    company_instance = Company.objects.filter(id=company_id_for_contact).first() 
    if not serializer.is_valid(): 
     print serializer.errors 
    data = serializer.validated_data 
    serializer.save(Company=company_instance) 
    headers = self.get_success_headers(serializer.data) 
    return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) 

と「のcompany_id」によるcompany_instance名前付きオブジェクトを取得し、それはあなたを助けることを願って!

関連する問題