DjangoのManyToManyFieldへの追加と削除

データ設計をするときに、多対多になるケースがあります。たいていのフレームワーク、というかO/Rマッパーは多対多をサポートしており、Djangoも例外ではありません。

が、多対多のモデルへの追加と削除が意外とわかりにくかったので、メモ。

class ServiceCategory(models.Model):

name = models.CharField(max_length=256)

class Service(models.Model):

servicecategory = models.ManyToManyField(ServiceCategory)
name = models.CharField(max_length=256)

というモデルがあったとして、Serviceというモデルへデータを登録する際のservicecategoryへの追加と削除です。

_service = Service()
_service.save()

_service.servicecategory.add(ServiceCategory.objects.get(id=1))

Serviceを保存して、IDが割り振られてからじゃないとManyToManyFieldの保存はできません。Djangoも多対多のリレーションをサポートするために中間テーブルを作成してくれます。この例ですと、「service_servicecategory」というテーブルがこっそり作られています。

その中間テーブルにServiceCategoryとServiceの関連性を保存するために、新しく登録されたServiceのIDが必要なんですね。

で、削除するには

_service.servicecategory.remove(ServiceCategory.objects.get(id=1))

と書きます。関連する多を全部まとめて一気に消す、とかクエリセットを使って消す、とかもできるのかもしれませんが、まだ試してないです。

もうちっとDjangoを使いこなせるようになりたいもんです。

Python2.5、Django1.1