Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.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 - Fatal编程技术网

Python 如何查找对实例的所有Django外键引用

Python 如何查找对实例的所有Django外键引用,python,django,Python,Django,如何找到对特定Django模型实例的所有直接外键引用 我想删除一条记录,但我想维护引用它的所有子记录,因此我试图在删除之前用另一条记录“交换”对旧记录的引用 类似的问题涉及收集器类。我试过: obj_to_delete = MyModel.objects.get(id=blah) new_obj = MyModel.objects.get(id=blah2) collector = Collector(using='default') collector.collect([obj_to_dele

如何找到对特定Django模型实例的所有直接外键引用

我想删除一条记录,但我想维护引用它的所有子记录,因此我试图在删除之前用另一条记录“交换”对旧记录的引用

类似的问题涉及收集器类。我试过:

obj_to_delete = MyModel.objects.get(id=blah)
new_obj = MyModel.objects.get(id=blah2)
collector = Collector(using='default')
collector.collect([obj_to_delete])
for other_model, other_data in collector.field_updates.iteritems():
    for (other_field, _value), other_instances in other_data.iteritems():

        # Why is this necessary?
        if other_field.rel.to is not type(first_obj):
            continue

        for other_instance in other_instances:
            setattr(other_instance, other_field.name, new_obj)
            other_instance.save()

# All FK references should be gone, so this should be safe to delete.
obj_to_delete.delete()
然而,这似乎有两个问题:

  • 有时
    collector.field\u updates
    包含对模型和字段的引用,这些引用与我的目标
    obj\u to\u delete
    无关
  • 我的最后一个
    obj_to_delete.delete()
    调用失败,IntegrityErrors抱怨仍然引用它的剩余记录,这些记录没有被收集器捕获
  • 我做错了什么


    我只需要一种方法来查找单个模型实例的所有FK引用。我不需要任何像Django的标准删除视图中使用的那种奇特的依赖项查找。

    您可以使用Django的反向外键支持

    假设您有两个模型,如下所示:

    class Foo(models.Model):
       name = models.CharField(max_length=10)
    
    class Bar(models.Model):
       descr = models.CharField(max_length=100)
       foo = models.ForeignKey(Foo)
    

    然后您就知道您可以执行
    bar\u instance.foo
    来访问它所键控的foo对象。但是,您可以在
    Foo
    实例上使用反向外键来获取指向它的所有
    Bar
    对象,例如,使用
    Foo.Bar\u集

    就个人而言,我认为最好的选择是避免级联删除

    使用适当的Django选项在相关模型中声明外键,例如

    on_delete=models.SET_NULL
    
    应该足够了

    借用@Joseph回答中的示例模型:

    class Foo(models.Model):
       name = models.CharField(max_length=10)
    
    class Bar(models.Model):
       descr = models.CharField(max_length=100)
       foo = models.ForeignKey(Foo, blank=True, null=True, on_delete=models.SET_NULL))
    
    如官方文件所述,以下是您可以使用和试验的预定义行为:

    • SET_NULL:将外键设置为NULL;这仅在null为空时才可能 对

    • SET_DEFAULT:将ForeignKey设置为默认值;违约 必须设置外键

    • SET():将ForeignKey设置为传递给SET()的值,或者如果 传入callable,即调用它的结果。在大多数情况下,为了避免在导入models.py时执行查询,需要传递callable:

    • 什么都不做:不要采取行动。如果您的数据库后端强制 引用完整性,这将导致IntegrityError,除非 在数据库字段中手动添加SQL ON DELETE约束
    from django.conf import settings
    from django.contrib.auth import get_user_model
    from django.db import models
    
    def get_sentinel_user():
        return get_user_model().objects.get_or_create(username='deleted')[0]
    
    class MyModel(models.Model):
        user = models.ForeignKey(settings.AUTH_USER_MODEL,
                                 on_delete=models.SET(get_sentinel_user))