2012-06-29 4 views
0

예를 들어. 내가 관리자 패널에서 내 개체를 저장하려고하면다 대다 관계의 장고 관리자 오류

class One(models.Model): 

    text=models.CharField(max_length=100) 

class Two(models.Model): 

    test = models.Integer() 
    many = models.ManyToManyField(One, blank=True) 

, 나는 같은 오류를 가지고 :

는 " '두'인스턴스가 다 대다 관계가 사용하기 전에 기본 키 값을 가질 필요가 . "

나는 django 1.3을 사용합니다. AutoField를 두 클래스에 추가하려고 시도했지만 작동하지 않습니다.

이것은 내 코드입니다.

from django.http import HttpResponse, HttpResponseRedirect 
from django.shortcuts import render_to_response, redirect 
from django.template import RequestContext 
from django.core.urlresolvers import reverse 
from project.foo.forms import FooForm 
from project.foo.models import Foo 
from project.fooTwo.views import fooTwoView 

def foo(request, template_name="foo_form.html"): 
    if request.method == 'POST': 
     form = FooForm(data=request.POST) 
     if form.is_valid(): 
      foo = Foo() 
      foo.name = request.POST.get("name") 
      foo.count_people = request.POST.get("count_people") 
      foo.date_time = request.POST.get("date_time") 
      foo.save() 
      return fooTwoView(request) 
    else: 
     form = FooForm() 

    return render_to_response(template_name, RequestContext(request, { 
     "form": form, 
    })) 

P. 나는 실패했다. 그것은 모델입니다. 나는 save 메소드에서 many to many를 사용했다. 사용하기 전에 검사를 추가하지만 도움이되지 않습니다.

class Foo(models.Model): 
    name = models.CharField(max_length=100, null=False, blank=False) 
    count_people = models.PositiveSmallIntegerField() 
    menu = models.ManyToManyField(Product, blank=True, null=True) 
    count_people = models.Integer() 
    full_cost = models.IntegerField(blank=True) 

    def save(self, *args, **kwargs): 
     if(hasattr(self,'menu')): 
      self.full_cost = self.calculate_full_cost() 
     super(Foo, self).save(*args, **kwargs) 

    def calculate_full_cost(self): 
     cost_from_products = sum([product.price for product in self.menu.all()]) 
     percent = cost_from_products * 0.1 
     return cost_from_products + percent 

나는이 날 도와입니다 방법 등

if(hasattr(self,Two)): 
     self.full_cost = self.calculate_full_cost() 

저장 해킹 시도,하지만 난 그 장고 방법이라고 생각하지 말아. 흥미로운 점은 관리자 패널의이 오류를 확인하지 않고 개체를 만들 수 있다는 것입니다. 이제 두 항목을 선택하고 저장하면 내 개체가 full_cost를 가지지 않지만 내 개체를 볼 때 관리자 패널이 내 선택을 기억하고 내 두 항목을 표시합니다. 내가 선택한 항목 ... 이유를 모르겠습니다.

어떻게 저장합니까?

답변

0

코드와 매우 몇 가지 문제가 있습니다. 가장 확실한 것은

1/사용자 입력 유효성 검사/위생 처리/변환을위한 양식을 사용하고 그 다음 santized/변환 된 데이터를 무시하고 요청에서 직접 unsanitized 입력을 얻는 것입니다. request.POST 대신 form.cleaned_data를 사용하여 데이터를 가져 오거나 완전히 채워진 Foo 인스턴스를 만드는 데 도움이되는 ModelForm을 더 잘 사용하십시오.

2/파이썬 메소드에서 암시 적 "this"(또는 "self"또는 무엇이든) 포인터가 없으므로 명시 적으로 "self"를 사용하여 인스턴스 속성을 가져와야합니다. 여기에 모델의 "저장"방법은 정말로 무엇 :

def save(self, *args, **kwargs): 
     # test the truth value of the builtin "id" function 
     if(id): 
      # create a local variable "full_cost" 
      full_cost = self.calculate_full_cost() 
     # call on super with a wrong base class 
     super(Banquet, self).save(*args, **kwargs) 
     # and exit, discarding the value of "full_cost" 

을 이제 귀하의 질문에 관하여 : Foo.save 분명히 M2M 관련 개체를 기반으로가 someting을 계산 할 수있는 권리 장소가 아니다. 계산을 실행하고 Foo를 업데이트하는 고유 한 메소드를 작성하고 저장 한 다음 m2m을 저장 한 후 호출하십시오 (힌트 : ModelForm이 m2m 관련 오브젝트를 저장하도록 처리 함). m2m_changed 신호 만 사용하십시오.

이것은 말하기를, 나는 당신이 파이썬과 장고를 배우는 데 몇 시간을 소비 할 것을 강력히 제안한다 - 그것은 많은 시간을 절약 해 줄 것이다.

+0

대단히 감사합니다. 나중에 내가 양식을 부엉 "자기"를 수정하는 코드를 변경하지만,이 게시물을 업데이 트 깜빡. form.cleaned_data 및 form.save에 대한 조언을 주셔서 감사합니다.이 코드를 복사하여 붙여 넣기 만하면됩니다. * m2m은 무엇인가요? 쓰기 방법을 알려주세요. 내가 이것에 대해 읽을 수있는 예나 링크를 보여주십시오. m2m_changed 신호는 어떻게됩니까? - 고마워요. 어쩌면 내 솔루션에서 이것을 사용합니다. –

+0

문서에 꽤 많은 코드 예제와 설명이 있습니다. 먼저 읽어야합니다. –

0

왜 대신 "OneToOneField"를 사용하지 대다

+0

주문 및 제품을 사용할 때 OneToOne을 사용하는 방법은 무엇입니까? 하나의 주문에는 많은 제품이 있고 하나의 제품에는 많은 주문이 있습니다. –

+0

오. 코드에 더 많은 것이 있는지 몰랐습니다. 다음 번에 전체 모델 코드를 가져 오십시오. P –

관련 문제