8

Django Tastypie API を作成していますが、ManyToMany関係に要素を追加する際に問題があります

例、models.py

class Picture(models.db):
    """ A picture of people"""
    people = models.ManyToManyField(Person, related_name='pictures',
        help_text="The people in this picture",
    )

class Person(models.db):
    """ A model to represet a person """
    name = models.CharField(max_length=200,
        help_text="The name of this person",
    )

資力:

class PictureResource(ModelResource):
    """ API Resource for the Picture model """
    people = fields.ToManyField(PersonResource, 'people', null=True,
        related_name="pictures", help_text="The people in this picture",
    )
class PersonResource(ModelResource):
    """ API Resource for the Person model """
    pictures = fields.ToManyField(PictureResource, 'pictures', null=True,
        related_name="people", help_text="The pictures were this person appears",
    )

私の問題はadd_person、画像リソースにエンドポイントが必要なことです。を使用するPUT場合は、画像内のすべてのデータを指定する必要があります。 を使用する場合PATCHでも、画像内のすべての人物を指定する必要があります。もちろん、/api/picture/:id/add_peopleURL を生成するだけで問題を処理できます。その問題は、それがきれいに感じられないことです。

別の解決策は、/api/picture/:id/peopleエンドポイントを生成することであり、新しいリソースのように , , を実行できますがGETPOSTこれPUTを実装する方法がわからず、このリソースの下に新しい人を作成するのは奇妙に思えます。

何かご意見は?

4

1 に答える 1

4

API リソースの save_m2m 関数をオーバーライドすることでこれを実装しました。モデルを使用した例を次に示します。

def save_m2m(self, bundle):
    for field_name, field_object in self.fields.items():
        if not getattr(field_object, 'is_m2m', False):
            continue

        if not field_object.attribute:
            continue

        if field_object.readonly:
            continue

        # Get the manager.
        related_mngr = getattr(bundle.obj, field_object.attribute)
            # This is code commented out from the original function
            # that would clear out the existing related "Person" objects
            #if hasattr(related_mngr, 'clear'):
            # Clear it out, just to be safe.
            #related_mngr.clear()

        related_objs = []

        for related_bundle in bundle.data[field_name]:
            # See if this person already exists in the database
            try:
                person = Person.objects.get(name=related_bundle.obj.name)
            # If it doesn't exist, then save and use the object TastyPie
            # has already prepared for creation
            except Person.DoesNotExist:
                person = related_bundle.obj
                person.save()

            related_objs.append(person)

        related_mngr.add(*related_objs)
于 2013-01-29T23:16:05.250 に答える