Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.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
Django 删除用作外键的对象_Django_Rest_Django Rest Framework - Fatal编程技术网

Django 删除用作外键的对象

Django 删除用作外键的对象,django,rest,django-rest-framework,Django,Rest,Django Rest Framework,我有以下型号: class Target(models.Model): name = models.CharField(max_length=100, blank=False) class SubTarget(models.Model): target = models.ForeignKey(Target, related_name='sub_targets') name = models.CharField(max_length=100, blank=True, n

我有以下型号:

class Target(models.Model):
    name = models.CharField(max_length=100, blank=False)


class SubTarget(models.Model):
    target = models.ForeignKey(Target, related_name='sub_targets')
    name = models.CharField(max_length=100, blank=True, null=True, default='')
例如,我运行下一个代码:

target = Target(name='test-target')
target.save()
sub_target = SubTarget(name='test-sub-target, target=target)
sub_target.save()
现在我有了带外键的sub_目标对象

我的目标序列化程序如下所示:

class TargetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Target
        fields = ('id', 'name', 'sub_targets')
        depth = 1
        read_only_fields = ('sub_targets',)
以及适当的看法:

class TargetDetail(generics.RetrieveUpdateDestroyAPIView):
    model = Target
    serializer_class = TargetSerializer

所以,没有什么可以阻止我删除带有外键的对象。此外,此操作还删除了相关的子_目标对象。我怎样才能避免这种行为

我不确定,但我想您是在问如何在删除目标对象时防止子目标对象被删除。默认情况下,Django在删除级联上进行模拟。您可以使用on_delete关键字控制此行为

因此:


您可以覆盖模型的删除操作,如:

class Target(models.Model):
    name = models.CharField(max_length=100, blank=False)

    def delete(self, *args, **kwargs):

        for robject in self._meta.get_all_related_objects():
            if robject is not None:
                q = Q(**{"%s__id" % robject.field.name: self.id})
                if robject.model.objects.filter(q).exists():
                    raise Exception("Item has active reference.")

        try:
            with transaction.atomic():
                super(Target, self).delete(*args, **kwargs)
        except Exception, exp:
            raise exp

请注意,如果相关对象与另一个对象没有反向关系,则它不起作用。

在寻找一种方法来检查模型实例是否可以在django中删除后,我遇到了许多示例,但没有按预期工作。希望这个解决方案能有所帮助

让我们首先创建一个抽象模型类,它可以被其他模型继承

class ModelIsDeletable(models.Model):
    name = models.CharField(max_length=200, blank=True, null=True, unique=True)
    description = models.CharField(max_length=200, blank=True, null=True)
    date_modified = models.DateTimeField(auto_now_add=True)

    def is_deletable(self):
        # get all the related object
        for rel in self._meta.get_fields():
            try:
                # check if there is a relationship with at least one related object
                related = rel.related_model.objects.filter(**{rel.field.name: self})
                if related.exists():
                    # if there is return a Tuple of flag = False the related_model object
                    return False, related
            except AttributeError:  # an attribute error for field occurs when checking for AutoField
                pass  # just pass as we dont need to check for AutoField
        return True, None

     class Meta:
        abstract = True
例子 假设我们有三种组织模式,部门和员工类型 一个组织中可以有这么多部门 一个组织有一种特殊的员工类型

class StaffType(ModelIsDeletable):
    pensionable = models.BooleanField(default=False)

class Organization(ModelIsDeletable):
    staff_type = models.ForeignKey(to=StaffType)


class Department(ModelIsDeletable):
    organization = models.ForeignKey(to=Organization, to_field="id")
比如说,在添加了一些信息之后,您希望删除一个组织模型实例 这已经和一个部门联系在一起了

例如我们有 组织机构表=>(名称=工程,主键=1) 部门表=>(名称=开发人员,组织机构=1,主键=1)

现在当你试图删除一个组织后,得到它的pk

a_org = Organization.objects.get(pk=1)
有了这个,你可以检查它是否可以删除

deletable, related_obj = a_org.is_deletable()

if not deletable:
    # do some stuff with the related_obj list

else:
    # call the delete function
    a_org.delete()

也许你可以尝试另一种方法,我刚刚用Django 1.8为我的项目得到了它

instance = get_object_or_404(MyModel, pk=pk)
eliminate = True
for robject in instance._meta.get_all_related_objects():
    if robject is not None:
        if robject.related_model.objects.filter(**{robject.field.name: instance}).exists() and eliminate:
            eliminate = False

if eliminate:
    instance.delete()
    # additional code
else:
    # additional code
    pass

延迟回复,但这也可以通过使用外键上的
model.PROTECT来避免

target=models.ForeignKey(
目标,相关的\u name='sub\u targets',在\u delete=models.PROTECT上
)

instance = get_object_or_404(MyModel, pk=pk)
eliminate = True
for robject in instance._meta.get_all_related_objects():
    if robject is not None:
        if robject.related_model.objects.filter(**{robject.field.name: instance}).exists() and eliminate:
            eliminate = False

if eliminate:
    instance.delete()
    # additional code
else:
    # additional code
    pass
class BaseModel(models.Model):

    def can_delete(self):
        # get all the related object to be deleted
        for related in get_candidate_relations_to_delete(self._meta):
            field = related.field
            if field.remote_field.on_delete == models.PROTECT:
                # check for relationship with at least one related object
                related = related.related_model.objects.filter(**{related.field.name: self})
                if related.exists():
                    return False, related
        return True, None

    class Meta:
        abstract = True