2009-06-01 3 views
1

업데이트 3으로 설정합니다 (이 먼저 읽기) : 장고 : 실제 개체와 일반 (콘텐츠 _) 분야를 설정하면 없음

예, 이것은 객체 "프로필"에 의해 발생 된 저장 된 없습니다. 같은 증상을 보이는 사람들에게는 도덕성이 입니다. "실제 개체를 할당 할 때 ForeignKey 필드가 None으로 설정되면 다른 개체가 저장되지 않았기 때문입니다."

는이 저장된 것을 100 % 확신하더라도, 장고의 클래스에 내가 콘텐츠 _/일반 외래 키를 사용하고 다시 ;-)


안녕,

을 확인합니다. 클래스의 인스턴스를 만들 수

선은 약이다이 : 두 에이전트 및 자원 콘텐츠 _ 필드입니다

tag = SecurityTag(name='name',agent=an_agent,resource=a_resource,interface=an_interface) 

.

대개의 경우,이 기능은 예상되는대로 작동하며 적절한 개체를 만듭니다. 하지만이 줄을 SecurityTag을 만들기 위해 호출하는 특정 사례가 있지만 에이전트 필드의 값이 None으로 끝나는 것 같습니다.

이제이 특별한 경우에 an_agent 값에 에이전트 유형의 기존 저장된 Django.model 객체가 포함되어 있는지 테스트합니다. 그리고 그렇게합니다.

그러나이 필드에는 결과 SecurityTag 레코드가 없음으로 표시됩니다.

나는 이것에 상당히 좌절감을 느낍니다. 라인을 따라 어딘가에있는 것으로 추측하고 있는데, 뭔가 an_agent에서 객체의 ID를 추출하려는 ORM의 시도에서 실패하고 있지만 오류 메시지도 예외도 발생하지 않습니다. an_agent 객체가 저장되어 있고 id 필드에 값이 있는지 확인했습니다.

누구나 이런 식으로 보았습니까? 아니면 아이디어가 있습니까?

====

업데이트 : "보안 태그"개체를 설명하는 코드이며, 여기에

것 : 10 일 후 정확히 같은 버그가 새로운 상황에서 나를 다시 물어왔다 기본적 간의 매핑

a)는 일반적인 콘텐츠 _ 우리의 시스템에서 "에이전트"로 알려진 허가 - 역할()의 일종,

B) 또한 일반적인 콘텐츠 _ 인 자원, (그리고 현재의 문제는 핀이 주어진다. 도끼 "프로필"),

및 c) "인터페이스"(기본적으로 액세스 유형 ... 예 : 특정 순간에 단지 문자열 "가시"또는 "편집")

class SecurityTag(models.Model) : 
    name = models.CharField(max_length='50') 
    agent_content_type = models.ForeignKey(ContentType,related_name='security_tag_agent') 
    agent_object_id = models.PositiveIntegerField() 
    agent = generic.GenericForeignKey('agent_content_type', 'agent_object_id') 

    interface = models.CharField(max_length='50') 

    resource_content_type = models.ForeignKey(ContentType,related_name='security_tag_resource') 
    resource_object_id = models.PositiveIntegerField() 
    resource = generic.GenericForeignKey('resource_content_type', 'resource_object_id') 

후, 나는이 할 : 그 전에

print "before %s, %s" % (self.resource,self.agent) 
t = SecurityTag(name=self.tag_name,agent=self.agent,resource=self.resource,interface=self.interface_id) 
print "after %s, %s, %s, %s" % (t.resource,t.resource_content_type,type(t.resource),t.resource_object_id) 

결과입니다은 "자원"변수 프로파일을 참조하지만 이후에는 ...

before phil, TgGroup object 
after None, profile, <type 'NoneType'>, None 

즉, t.resource_content_type의 값이 "프로필"로 설정되어있는 동안은 그 밖의 모든 것이 없음입니다. 이전에이 문제가 발생했을 때 제네릭 유형에 할당하려고했던 작업을 다시로드하여 "해결"했습니다. 이것이 일종의 ORM 캐시 문제인지 궁금해지기 시작했습니다 ... 실제 "객체"가 아닌 "self.resource"변수가 있습니다.

프로필 하나가 저장되지 않았을 가능성이 있습니다. 그러나이 코드는 프로파일에 대한 after_save 신호의 결과로 호출됩니다. (기본 권한을 설정하고 있습니다.) 프로필 저장이 커밋되지 않았습니까?

업데이트 2 : 아래 매튜의 제안 다음, 나는 프로필 _get_pk_value을()이없는 말을 폭파했다

print self.resource._get_pk_value() and self.resource.id 

을 추가

+0

이것은 분명히 의도 된 동작이 아닌 버그이며 솔직히 장고보다 코드 어딘가에있을 가능성이 훨씬 높습니다 (후자는 가능하지만). 따라서 관련 코드를 게시하거나 게시판 덤프에 연결할 수 없다면 유용한 답을 찾기가 어려울 것입니다. –

+0

"before"print 문에 self.resource._get_pk_value() 및 self.resource.id를 추가하고 결과와 함께 질문을 편집 할 수 있습니까? 전자가 어떤 이유로 든 반환한다면 나는 이것이 일어나고있는 이유 일 수 있습니다. –

+0

Brilliant! 매튜, 네가 옳았다. 그것은 그 대상이 실제로 구원받지 못했다는 것을 보여주었습니다. 어느 쪽이 나에게 버그를 지적했다. 답변을하면 보너스를드립니다. – interstar

답변

4

다음은 장고 코드를 통과 한 것으로 나타났습니다. 생성자를 통해 모델 객체의 새 인스턴스를 만들 때 모든 일반 객체 참조에 대해 신호를 통해 호출되는 사전 초기화 함수가 생성됩니다.

전달하는 객체를 직접 저장하는 것이 아니라 유형 및 기본 키를 저장합니다.

개체가 유지되고 ID가 있으면 나중에 필드를 가져올 때 데이터베이스에서 해당 개체를 검색하므로 제대로 작동합니다.

그러나 개체에 ID가없는 경우 가져 오기 코드는 아무 것도 반환하지 않고 getter는 None을 반환합니다.

코드는 instance_pre_init__get__ 기능에서 django.contrib.contenttypes.generic.GenericForeignKey으로 볼 수 있습니다.

1

이 정말 내 질문에 대답이나 내 호기심을 충족하지 않습니다 하지만 SecurityTag 생성자에서 사용하기 전에 an_agent 객체를 데이터베이스에서 바로 꺼내면 작동하는 것 같습니다.

이전에는 get_or_create를 사용하여 이전에 작성한 사본을 전달했습니다. 이 오래된 인스턴스가 어떻게 든 시대에 뒤쳐 졌거나 범위를 벗어 났습니까?

+0

이전 인스턴스가 악마를 채우고 전달하는 사이에 저장되었는지 확인 했습니까? –