2013-12-10 8 views
5

Iniziamo dai modelli utilizzati nei documenti django sulla relazione M2M che utilizza l'argomento through per indicare il modello che fungerà da intermediario.Come lavorare con la relazione M2M in django-rest

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

    def __unicode__(self): 
     return self.name 

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

    def __unicode__(self): 
     return self.name 

class Membership(models.Model): 
    person = models.ForeignKey(Person) 
    group = models.ForeignKey(Group) 
    date_joined = models.DateField() 

    class Meta: 
     ordering = ['date_joined'] 

Si supponga ora voglio riposare lettura-scrittura vista per il modello di Gruppo che contiene anche tutta la persona all'interno di ogni gruppo, ordinato dal campo date_joined. La serializzazione JSON vorrei ottenere è il seguente (i membri sono descritti solo con il loro id):

{ 
    "id": 1, 
    "name": "U2", 
    "members": [ 
     20, 
     269, 
     134, 
     12, 
    ] 
} 

ho scritto un serializzatore:

class GroupSerializer(serializers.ModelSerializer): 
    members = serializers.SlugRelatedField(source='membership_set', 
              many=True, 
              read_only=False, 
              slug_field='person_id', 
              required=True) 

    class Meta: 
     model = Group 
     fields = ('id', 'name', 'members') 

Mentre per le operazioni di lettura funziona bene, non per scrivere Come devo definire il serializzatore in modo tale che, data la serializzazione sopra definito, si procederà da:

  1. Creare l'oggetto Gruppo
  2. Aggiungi ciascuno membri al gruppo (con la creazione di un oggetto appartenenza)

risposta

2

Da here è possibile vedere che ciò che si sta tentando di fare funziona solo per le operazioni di lettura. Questo è un problema comune per DRF, come affermato dal suo creatore, Tom Christie, nel commento this.

Inoltre, per la serializzazione JSON che si desidera, si consiglia di utilizzare un campo relativo al PK, come mostrato in here, sebbene ciò non sia di aiuto per la creazione dell'oggetto Gruppo e l'aggiunta di membri. Dovrai scrivere quel codice te stesso.

Spero che questo aiuti.

Modifica

Codice frammento per l'aggiunta di ogni persona al Gruppo da appartenenze che creano:

def post_save(self, obj, created=False): 
    # obj represents the Group object 
    if created: 
     # Test to see if the Group was successfully created 
     members = self.request.DATA.get('members', None) 
     if members not None: 
      for id in members: 
       person = Person.objects.get(id=id) 
       membership, m_created = Membership.objects.get_or_create(person=person, group=obj) 
       # Here you can use m_created to see if the membership already existed and to do whatever else you need. 

Questa implementazione presuppone che sia stata dichiarata la tua date_joined con auto_now. Altrimenti, dovresti anche passarlo come parametro.

+0

Grazie per la risposta chiara che mi ha fornito anche il collegamento alla parte pertinente della documentazione o la risposta dell'autore sul punto. È un peccato che quello che stavo cercando di fare non sia molto supportato dal framework. Potresti per favore suggerirmi un modo per portare a termine il compito scrivendo il codice da solo? Qual è la strada giusta? Grazie ancora! – Dragster

+0

Sono felice di poterti aiutare :) Per quanto riguarda la parte di creazione, puoi farlo in due punti: nel metodo ** post/crea ** o nel metodo ** post_save **. Suggerisco di farlo nel ** post_save ** perché ciò significa che stai permettendo al framework di creare l'oggetto Group e tutto ciò che resta da fare è aggiungere i membri. Modificherò la mia risposta con un piccolo snippet di codice su come usare questo metodo. – AdelaN

+0

Grazie mille, il vostro supporto è molto apprezzato! – Dragster