Я думаю, что лучший способ приблизиться оба ваших желаемого поведения не с сигналами, а с переопределяется сохранить() и удалить() метод на through
столе, который вы бы определить в явном виде с помощью аргумента through
см.: https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ManyToManyField.through. и это: https://docs.djangoproject.com/en/dev/topics/db/models/#overriding-predefined-model-methods
Что-то вроде этого:
# -*- coding: utf-8 -*-
from django.db import models
class Item(models.Model):
# fields
# ...
class Collection(models.Model):
items = models.ManyToManyField(Item, related_name="collections", through="CollectionItem")
# other fields
# ...
class CollectionItem(models.Model):
collection = models.ForeignKey(Collection)
item = models.ForeignKey(Item)
def save(self, *args, **kwargs):
# Only allow this relationship to be created on some_condition
# Part 1 of your question.
if some_condition:
super(CollectionItem, self).save(*args, **kwargs)
# Update some fields on Collection when this
# relationship is created
# Part 2 of your question (1/2)
self.Collection.updateSomeFields()
def delete(self, *args, **kwargs):
collection = self.collection
super(CollectionItem, self).delete(*args, **kwargs)
# Update some fields on Collection when this relationship
# is destroyed.
# Part 2 of your question (2/2)
collection.updateSomeFields()
Кстати, вы обнаружите, что добавление отношения будет причины сохранения сигнала, на этом счете модели.
И в отношении сигналов, когда у вас есть сквозная таблица на месте, вы сможете слушать сигналы pre_save и/или post_save, но ни один из них не позволит вам прямо наложить вето на создание отношений.
Если одна или обе модели предоставлены третьей стороной, и вы действительно не можете создать сквозную таблицу, тогда да, маршрут сигнала может быть единственным способом.
https://docs.djangoproject.com/en/dev/ref/signals/#m2m-changed
В этом случае, вы можете слушать для m2m_changed события и запуска обновления ваших объектов коллекции (часть 2 вашего вопроса) и задним числом удалить ненадо отношения (созданные нами часть 1 вашего вопроса). Тем не менее, поскольку этот последний бит является уродливым kludgy, я бы придерживался явной сквозной таблицы, если можно.
Для проблемы 1 вы, вероятно, должны использовать цикл очистки формы для проверки данных (что облегчает обмен сообщениями проверки), которое затем отправляется на [save_m2m] (https: //docs.djangoproject.com/en/dev/themes/forms/modelforms/# the-save-method) –
@Hedde: Я бы предпочел решение, близкое к моделям, потому что мои данные скорее всего не будут изменены из формы. (Скорее всего, с помощью инструментов CLI и открытого API). – Constantinius
Вы можете перезаписать методы сохранения модели, по крайней мере, для части логики, но если вы реализуете API, кажется, что такая логика принадлежит уровню авторизации API. Tastypie - отличный богатый API, который хорошо сочетается с Django. –