2009-12-16 1 views
3

모델의 인스턴스를 삭제하려고합니다. 다른 클래스의 다른 인스턴스가없는 외래 키가있는 경우에만 삭제하고 싶습니다. 그것. 장고 문서에서 :Django 모델 ON DELETE CASCADE 정책에서 대신에 DELETE RESTRICT를 에뮬레이트하십시오. 일반 솔루션

장고 객체를 삭제하면, 그것은 DELETE CASCADE ON은 SQL 제약의 동작을 에뮬레이트

- 즉이 삭제 될 대상을 가리키는 외래 키를 가지고 물건이 함께 삭제됩니다 그것으로. 주어진 예에서

: 오류를 인쇄해야

tA = TestA(name="testA1") 
tB = TestB(name="testB1") 
tB.testAs.add(tA) 

t = TestA.objects.get(name="testA1") 

if is_not_foreignkey(t): 
    t.delete() 
else: 
    print "Error, some instance is using this" 

: 내가 좋아하는 일을하고 싶습니다

class TestA(models.Model) 
    name = models.CharField() 

class TestB(models.Model) 
    name = models.CharField() 
    TestAs = models.ManyToManyField(TestA) 

# More classes with a ManyToMany relationship with TestA 
# ........ 

. 나는이 경우 check t.TestB_set()와 같이 foreignkey가 설정 한 특정 인스턴스를 검사 할 수 있다는 것을 알고 있지만 주어진 모델에 대해보다 일반적인 해결책을 찾고있다.() 장고 1.3에서 제거

# Check foreign key references 
    instances_to_be_deleted = CollectedObjects() 
    object._collect_sub_objects(instances_to_be_deleted) 

    # Count objects to delete 
    count_instances_to_delete = 0 
    for k in instances_to_be_deleted.unordered_keys(): 
     count_instances_to_delete += len(instances_to_be_deleted[k]) 

    if count_instances_to_delete == 1: 
     object.delete() 
    else: 
     pass 

답변

0

확인 관련 개체의 길이는

t=TestA.objects.get(name="textA1") 
if not t.testB_set.all().count():#related members 
    t.delete() 
+0

특정 사례에는 효과가 있지만 일반적인 해결책을 원했기 때문에 모든 모델에 대해 다른 삭제 테스트를 작성하고 다른 오브젝트가 참조 할 경우이를 업데이트해야합니다. – plmet

2

드디어이 Nullable ForeignKeys and deleting a referenced model instance를 사용하여 해결, 솔루션 등이 보인다 :

from compiler.ast import flatten 
from django.db import DEFAULT_DB_ALIAS 
from django.contrib.admin.util import NestedObjects 

def delete_obj_if_no_references(obj): 
    collector = NestedObjects(using=DEFAULT_DB_ALIAS) 
    collector.collect([obj]) 
    objs = flatten(collector.nested()) 
    if len(objs) == 1 and objs[0] is obj: 
     obj.delete() 
     return True 
    return False 
0

CollectedObjects - 여기에 현재의 방법입니다 :