Django Python 3.x - удаление переопределения OneToOneField () с ContentTypes - PullRequest
1 голос
/ 22 апреля 2020

Сценарий: существуют разные типы услуг, например, стирка одежды, room_cleaning и room_maintenance. Каждый из этих сервисов имеет общие поля, например, service_date.

По сценарию у меня есть модель для каждой услуги и модель Service с общими полями. отношение между Service моделью и каждой моделью сервиса: OneToOneField.

Я пытался переопределить функцию delete() в модели Service, следуя этому ответу , и это работает для меня, но только для одной услуги (как колесо в self.wheel.delete()). но если я хочу удалить по типу службы? как добиться этого подхода?

my models.py :

class ClothesWashing(models.Model):
    # special fields for clothes_washing
    service = models.OneToOneField(Service, on_delete=models.DO_NOTHING, null=True)

class RoomCleaning(models.Model):
    # special fields for room_cleaning 
    service = models.OneToOneField(Service, on_delete=models.DO_NOTHING, null=True)

class Service(models.Model):
    # common fields for all services

    def delete(self, *args, **kwargs):
        #here I wanna "roomcleaning" attribute to be dynamic upon content type
        self.roomcleaning.delete()
        return super(self.__class__, self).delete(*args, **kwargs)

1 Ответ

1 голос
/ 22 апреля 2020

Вы можете установить параметры on_delete на CASCADE:

class ClothesWashing(models.Model):
    # special fields for clothes_washing
    service = models.OneToOneField(Service, <b>on_delete=models.CASCADE</b>, null=True)

class RoomCleaning(models.Model):
    # special fields for room_cleaning 
    service = models.OneToOneField(Service, <b>on_delete=models.CASCADE</b>, null=True)

on_delete=&hellip; параметр [Django -doc] указывает, что должно произойти, когда элемент, на который он ссылается, удаляется. Поэтому, если Service удален, и существует модель ClothesWashing, которая ссылается на него, то вы можете указать, что делать.

Используя CASCADE [ Django -doc] , вы также удалите связанный объект ClothesWashing или как указано в документации:

Каскадное удаление. Django эмулирует поведение ограничения SQL ON DELETE CASCADE, а также удаляет объект, содержащий ForeignKey.

Лучше реализовать его с помощью этих триггеров, поскольку такие методы, как .delete() are not всегда вызывается ORM при массовом удалении. Таким образом, Service.objects.all().delete() удалит все службы, но никогда не вызовет .delete() метод вашего Service. Определяя триггеры, вы указываете Django, что должно происходить с элементами, относящимися к нему.

В этом конкретном c случае, возможно, вы захотите работать с наследованием модели [Django -doc] . Django может реализовывать некоторые шаблоны logi c (например, OneToOneField s для родительской модели и т. Д. c.).

EDIT : если вы хотите удалить обслуживание, если дано ClothesWashing, RoomCleaning, et c. удалены, вы можете переопределить метод .delete(), чтобы удалить его, например, вы можете создать абстрактный базовый класс с помощью:

class ServiceBase(models.Model):
    # special fields for clothes_washing
    service = models.OneToOneField(Service, on_delete=models.CASCADE, null=True)

    def delete(self, *args, **kwargs):
        service = self.service
        super().delete(*args, **kwargs)
        self<b>.service.delete()</b>

    class Meta:
        <b>abstract = True</b>

class ClothesWashing(<b>ServiceBase</b>):
    # &hellip;
    pass

class RoomCleaning(<b>ServiceBase</b>):
    # &hellip;
    pass

Но, вероятно, если вы используете ORM, в конечном итоге некоторые объекты не будут удален из-за указанных способов обойти это.

...