Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何避免Django多对多关系中的孤立记录?_Python_Django_Django Models_Many To Many - Fatal编程技术网

Python 如何避免Django多对多关系中的孤立记录?

Python 如何避免Django多对多关系中的孤立记录?,python,django,django-models,many-to-many,Python,Django,Django Models,Many To Many,如何确保在从具有多对多关系的Django表中删除记录时不会留下任何孤立记录 我创建了三个Django模型,允许用户创建代表他们想要参加的活动(如电影、音乐会和体育赛事)的项目列表。由于每个用户可以在一个列表中包含一个或多个项目(即活动),并且多个用户的一个列表中可能包含相同的项目(活动),因此列表和项目之间存在多对多关系: class Type(models.Model): TYPES = ( (1, 'Movie'), (2, 'Concert'),

如何确保在从具有多对多关系的Django表中删除记录时不会留下任何孤立记录

我创建了三个Django模型,允许用户创建代表他们想要参加的活动(如电影、音乐会和体育赛事)的项目列表。由于每个用户可以在一个列表中包含一个或多个项目(即活动),并且多个用户的一个列表中可能包含相同的项目(活动),因此列表和项目之间存在多对多关系:

class Type(models.Model):
    TYPES = (
        (1, 'Movie'),
        (2, 'Concert'),
        (3, 'Sport'),
    )
    type = models.CharField(_('type'), max_length=16)
    class Meta:
        db_table = 'type'


class List(models.Model):
    user = models.ForeignKey(User)
    type = models.ForeignKey(Type, help_text=_('Type of list'))
    name = models.CharField(_('list'), max_length=128, help_text=_('Name of list'))
    class Meta:
        db_table = 'list'
        unique_together = (('user', 'type', 'name'), )   # Ensure no duplicate lists

class Item(models.Model):
    """item contains the pk of a movie, concert, or sporting event record"""
    lists = models.ManyToManyField(List, related_name='items').   # Results in creation of item_lists linking table
    type = models.ForeignKey(Type, help_text=_('Type of item'))
    item = models.IntegerField(_('item'), help_text=_('Item in list'))
    class Meta:
        db_table = 'item'
        unique_together = ('item', type',)
每当我创建一个新的列表项时,我都会使用Django的get_或_create()QuerySet方法

为了防止孤立记录,我认为每当我删除整个列表或列表中的一个或多个项目时,我还需要检查删除的项目是否包含在任何其他列表中,如果没有,则从项目表中删除这些项目。伪代码可能如下所示:

items_to_delete = (single item or items from a list)
for item in items_to_delete:
    if item is not in item_lists linking table:   # Prevent orphan records
        delete item from item table
    delete item from item_lists linking table
是否有“标准”Django方法来执行上述记录删除?我是否应该重写Django的object delete方法,以便在链接表中没有更多实例的情况下,它也从item表中删除该项?或者这是创建Django信号的情况

其次,我是否应该将上述删除逻辑包装到Django原子数据库事务中?难道一个进程不可能对现有项执行get_或create并获取它,因为它认为该项在表中,但第二个进程在第一个进程可以在链接表中为其创建记录之前从项表中删除该项吗?

您看过使用

至于信号的原子事务,请查看

from django.db.models.signals import post_delete
from django.dispatch import receiver

@receiver(post_delete, sender=models.List)
def check_orphan_items(sender, instance, **kwargs):
    for item in instance.items.all():
        if not item.lists.all().exists():
            item.delete()