2016-02-22 14 views
6

Sono un po 'nuovo per Django e Django-REST quindi ti prego di sopportare me. Forse la risposta è nella documentazione, quindi se mi sono perso, mi scuso in anticipo.Django REST - Crea oggetto con chiave esterna utilizzando i serializzatori

Obiettivo: Vorrei creare un oggetto EquipmentInfo i cui attributi includono chiavi esterne preesistenti (EquipmentType e EquipmentManufacturer).

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 

Supponendo che ho già rilevanti EquipmentType e gli oggetti creati EquipmentManufacturer, vorrei aggiungere un altro oggetto EquipmentInfo. Qual è il modo appropriato per impostare il mio serializzatore EquipmentInfo in modo che possa passare informazioni

{ 
"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 
} 

o meglio ancora:

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

Ogni aiuto è apprezzato.

+0

Potete chiarire? Il problema in cui si desidera essere in grado di ottenere i serializzatori nidificati quando viene eseguito, ma durante la pubblicazione, si desidera solo passare gli ID record per gli oggetti esistenti? – dkarchmer

+0

Quando uso l'API sfogliabile per pubblicare un nuovo record 'EquipmentInfo', viene visualizzato un errore che dice' equipment_type' e 'manufacturer_name' già esistenti. Questo è previsto perché ho già i record "EquipmentType" e "EquipmentManufacturer". Ma ora vorrei aggiungere un nuovo record 'EquipmentInfo'. Quindi in un certo senso, sì, voglio solo passare gli ID dei record per gli oggetti esistenti. Idealmente, qualunque dispositivo che invii le informazioni non dovrebbe conoscere il valore del campo id e solo essere in grado di usare 'equipment_type' e' manufacturer_name'. Questo aiuta a chiarire? – mcaro

risposta

1

L'utilizzo di serializzatori annidati rende davvero difficile per i messaggi (se funziona anche, in quanto non funzionava) e, dati i vostri modelli semplici, raccomanderei di rimuoverli.

mi consiglia di aggiungere le API per

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

(o qualunque nome che si desidera utilizzare). I modelli type e manufacturer dovrebbero essere viste a vaniglia e utilizzare i serializzatori esistenti.

Per info, rimuovere i due serializzatori nidificate:

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

Dopo di che, si dovrebbe essere in grado di fare post utilizzando:

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 
} 

Nel mio caso, mi piace che lo rende il Gets più conveniente quindi aggiungo i campi di sola lettura per restituire un nome (o anche l'intero record serializzato):

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 

Spero che questo aiuti.

0

ho anche affrontato il problema, e hanno risolto, il seguente è il mio passo, spero che sarà utile 1.company modello e il contatto modello come segue:

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 creare A Nuovo Serializer Named CompanyReferenceSerializer, e 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.Viewset come segue, nel backend, ho l'oggetto denominato company_instance secondo il 'company_id'

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) 

e ho successo inserisco un record nel company_contact, spero che ti può aiutare!

Problemi correlati