2009-12-12 3 views
2

사용자가 여러 관련 요소를 만든 다음 해당 요소를 데이터베이스에 저장할 수있는 웹 앱을 개발 중입니다. webapp는 데이터베이스에 기본 키가 무엇인지 알지 못하므로 각 요소에 UUID를 할당합니다. 이러한 UUID는 데이터베이스의 각 요소와 함께 저장됩니다. webapp이 데이터를 웹 서버에 보내 데이터베이스에 저장하면 JSON을 사용하여 모든 것을 인코딩합니다. JSON은 serializers.deserialize('json', DATA)을 사용하여 웹 서버에 의해 deserialize됩니다. 그러나 일부 모델에는 외래 키가 있으며이 외래 키는 데이터베이스 ID가 아닌 연관된 요소의 UUID에 대한 참조로 JSON 페이로드로 전송됩니다. 소스 2의 id 값이 있고 대상 (12)의 id 값이, 문제는이 같은 JSON으로 직렬화 될 수 있던 경우에Django의 모델에 임시 필드를 추가하려면 어떻게합니까?

class Link(models.Model): 
    uuid = models.CharField(max_length=32) 
    source = models.ForeignKey(Node, related_name='source') 
    target = models.ForeignKey(Node, related_name='target') 

:

{"uuid": "[some long uuid]", 
"source": 2, 
"target": 12} 
예를 들어, 우리는 간단한 링크 개체를 가질 수있다 이 경우 우리는 그들이 아직 설정되어 있지 않은 아마 때문에, 소스 및 대상의 데이터베이스 ID를 알 수 없기 때문에

하지만, 내가 할 수있는 최선이 같은 UUID의에서 통과되어

{"uuid": "[some long uuid]", 
"sourceuuid": "[uuid of source]", 
"targetuuid": "[uuid of target]"} 

불행하게도 th 내가 serializers.deserialize 데이터를 호출했을 때 FieldDoesNotExist: Link has no field named u'sourceuuid' 예외가 발생합니다.

나는 UUID를 전달할 수있는 방법을 찾고 싶습니다. 그런 다음 적절한 부분을 저장하거나 필요할 때마다 ID를 채우면됩니다. 나는 정수를 저장하기위한 공간이 훨씬 적기 때문에 sourceuuidtargetuuid을 데이터베이스에 저장하고 싶지 않고 표시도 빨라야합니다.

그래서 내가 찾고있는 것은 임시 필드입니다. 하나는 인스턴스화 및 참조 할 수 있지만 다시 데이터베이스에 저장되지 않습니다. 어떻게 그런 일을 만들어 낼 수 있을지에 대한 아이디어가 있습니까? 지금까지

감사합니다 도움에 대한 더 명확한 설명과

UPDATE, 나는 그들이 파이썬 객체를이고 나는 객체에 대한 임의의 필드를 할당 할 수 있음을 알고 있어요. 그러나 문제는 serializers.deserialize('json', INDATA)이 오류를 발생시키는 것입니다. 그러나

ser='''[{"pk": 1, "model": "myapp.link", 
     "fields": {"uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", 
        "source": 2, 
        "target": 12}}]''' 
serializer.deserialize('json',ser) 

, 내가 무엇을 제공 할 수있는 것은 이것이다 :

ser='''[{"pk": 1, "model": "myapp.link", 
     "fields": {"uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", 
        "sourceuuid": "11111111-2222-3333-4444-555555555555", 
        "targetuuid": "66666666-7777-8888-9999-000000000000"}}]''' 
serializer.deserialize('json',ser) 
FieldDoesNotExist: Link has no field named u'sourceuuid' 

이유 참고로

여기에 자신의 ID가 외부 키를 가지고, 디시리얼라이저가 좋아하는 JSON의 덩어리입니다 deserialize에 실제 필드가 필요하기 때문에 실제 필드가되도록 더미 필드가 필요합니다.

답변

1

필요한 정보를 저장하는 비 materialized django 모델에 외래 키를 정의 할 수 있습니다.

은 기본 키와 같은 UID를 사용하지 왜 외부 키 (또는 OnetoOne 키가) 정의되는, 단지

class _meta: 
    managed = False 
+0

이것은 가장 가까이에 있지만 예상대로는 아닙니다. 구체화되지 않은 Django 모델에 대한 ForeignKey는 여전히 참조하는 테이블에 컬럼을 추가합니다. 그러나'sourceuuid'와'targetuuid'를 새 필드로 사용하여 구체화되지 않은 전체 서브 클래스를 만들면 어딘가에 도착할 수 있습니다. 새로운'LinkJSON' 클래스에서 비 직렬화 한 다음 UUID를 매핑 한 다음 필드를'Link' 클래스에 복사합니다. 그것은 꽤 아니지만 그것은 다소 효과가 있습니다. 파이썬이 기본 클래스에 캐스트를 입력하는 쉬운 방법이 있다면 훨씬 더 좋을 것입니다. – Pridkett

+0

나는이 대답을 내가 받아들이고 싶었던 것에 가장 가까웠 기 때문에 받아 들인다. 나는 펑키 서브 클래 싱을 수행하고 JSONSerializer의 서브 클래스를 만들어 모든 것을 처리해야했지만 지금은 작동합니다. 불행히도, 꽤 구체적인 솔루션이 되었기 때문에 StackOverflow에 그 전체를 게시 할 수는 없습니다. – Pridkett

0

나는 그런 임시 필드를 모른다. 그것은 좋은 것입니다 :)

내 제안이 있습니다 : JSON을 받고 그것을 개체로 만드는보기에서 속성을 확인하십시오. "실제"속성 (외래 키 또는 M2M이 아님) 만있는 객체를 만듭니다. 그들에게 임의의 속성을 할당 할 수 있지만 (instance.arbitrary_attribute = something) 좋은 lookup 메커니즘 (Model.objects.filter (...))을 얻지는 못합니다. 모든 오브젝트를 작성한 후에는 오브젝트를 다시 반복하고 각 FK에 대해 링크의 UUID가있는 오브젝트를 찾아서 링크하십시오 (instance.id 사용).

+0

설정 primary_key와는 내가 JSON 모든 muckity의 오물을 피하려고 노력하고있어. 그것은 내가 코드에서 오류와 문제점을 일으킬 수있는 또 다른 곳입니다. 그것은 효과가 있지만, 지저분한 최후의 수단입니다. – Pridkett

0

일반 파이썬 속성을 만들 수 있습니다.이 속성은 db에 저장되지 않습니다. 좋아요 :

+0

설명을 보려면 내 업데이트를 참조하십시오. 'deserializer' 메소드는'Field'가 아닌 데이터를 처리하는 것을 거부합니다. 이 메소드는 예외를 throw합니다. – Pridkett

2

정확하게 무엇을 하려는지 잘 모르겠습니다. 그러나 Django 모델은 Python 객체 일 뿐이며 Python 객체는 완전히 동적입니다. 따라서 모델에 uuid 필드가 정의되어 있지 않은 경우에도 obj.uuid = whatever을 수행하는 것이 좋습니다.

+0

질문을 좀 더 자세히 업데이트했습니다. 'deserialize'가 예외를 던질 것이기 때문에 실제'Field'가 필요합니다. – Pridkett

0

을 배치하는 새로운 모델에 이렇게하려면? 진정한

class Node(models.Model): 
    uuid = models.CharField(max_length=32, primary_key=True) 
    [...] 


class Link(models.Model): 
    uuid = models.CharField(max_length=32, primary_key=True) 
+0

나는 그것에 대해 생각해 왔고, 내가 할 수있는 다른 방법을 찾지 못하면. 그러나 UUID는 데이터베이스에서 더 많은 공간을 차지하며 int보다 인덱스 및 검색 속도가 느립니다. – Pridkett

+0

당신이하려고하는 것이 무엇인지는 매우 분명하지 않습니다. 당신이 당신에 대한 더 자세한 정보를 가지고 있다면 좋은 해결책이 될 것입니다. –

관련 문제