2013-04-09 6 views
5

장고 모델 인스턴스를 복제 할 때 'pk'필드를 정리할 때 사용했습니다.상속 된 장고 모델 인스턴스 복제

이이 걸릴 : (내가 장고 쉘을 사용하고) 이제

class ModelA(models.Model): 
    info1 = models.CharField(max_length=64) 

class ModelB(ModelA): 
    info2 = models.CharField(max_length=64) 

class ModelC(ModelB): 
    info3 = models.CharField(max_length=64) 

을의 인스턴스를 만들 수 있도록하고 '보통'방법으로 그것을 복제 : 이 상속 된 모델 작동하지 않을 것

In [16]: c.pk =None 

In [17]: c.id=None 

In [21]: c.modela_ptr_id=None 

In [22]: c.modelb_ptr_id=None 

In [23]: c.save() 

In [24]: c.pk 
Out[24]: 2L <---- successful clone containing info1,info2,info3 from original instance 

In [25]: ModelC.objects.all() 
Out[25]: [<ModelC: ModelC object>, <ModelC: ModelC object>] 

나는 것을 발견 : 내가 찾은

In [1]: c=ModelC(info1="aaa",info2="bbb",info3="ccc") 

In [2]: c.save() 

In [3]: c.pk 
Out[3]: 1L 

In [4]: c.pk=None <------ to clone 

In [5]: c.save() <------ should generate a new instance with a new index key 

In [6]: c.pk  
Out[6]: 1L   <------ but don't 

In [7]: ModelC.objects.all() 
Out[7]: [<ModelC: ModelC object>] (only one instance !) 

유일한 방법은 어떻게하는 것이 었습니다 매우 추악한데 상속 된 모델에서 인스턴스를 복제하는 더 좋은 방법이 있습니까?

+0

기본 모델을 단독으로 사용 하시겠습니까? 아니면 상속 모델 만 사용 하시겠습니까? 자체적으로 기본 모델을 사용할 필요가 없다면 [추상 기본 클래스] (https://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base)를 사용해야합니다. -classes). –

+0

사실 Django 모델의 상속은 나쁜 습관으로 간주 될 수 있습니다. 추상 기본 클래스 또는 외래 키를 사용할 수 있습니다. – PepperoniPizza

+0

save() 메서드를 붙여 넣을 수 있습니까? 모델에서 pk를 어떻게 설정하고 있습니까? – PepperoniPizza

답변

0
c=ModelC(info1="aaa",info2="bbb",info3="ccc") 
# creates an instance 

c.save() 
# writes instance to db 

c.pk=None 
# I doubt u can nullify the auto-generated pk of an existing object, because a pk is not nullable 
c.save() 
# if I'm right nothing will happen here. 

그래서 c는 항상 동일한 개체입니다. 복제하려는 경우 새 객체를 생성해야합니다. 어느 ModelC 내에서 생성자 :

c2=ModelC(c.info1, c.info2, c.info3) 

그런 다음 C2 c는 자신의 PK

에도 불구하고 동일합니다 :

def __init__(another_modelC_obj=null, self): 
    if another_modelC_obj: 
     # for every field in another_modelC_obj: do self.field = another_modelC_obj.field 
    super().__init__() 

그래서 당신은

c2=ModelC(c) 

갈 수 또는 직접 호출