0

例えば。

class One(models.Model):

     text=models.CharField(max_length=100)

class Two(models.Model):

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

管理パネルでオブジェクトを保存しようとすると、次のようなエラーが発生します。

「多対多の関係を使用するには、'Two' インスタンスに主キーの値が必要です。」

私はジャンゴ1.3を使用しています。Two クラスに 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,
    }))

PS私は自分の失敗を見つけました。モデル中です。save メソッドで多対多を使用しました。使用前にチェックを入れていますが、どうにもなりません。

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()

これは私を助けてくれますが、それがジャンゴのやり方だとは思いません。興味深いのは、この管理パネルの表示エラーをチェックせずに、オブジェクトを作成することです。ここで、Two からアイテムを選択して保存すると、オブジェクトに full_cost がありませんが、オブジェクトを表示すると、管理パネルが選択を記憶し、選択した Two アイテムを表示します...理由がわかりません。

これを保存するにはどうすればよいですか?

4

2 に答える 2

0

コードにはかなりの問題があります。最も明白なものは

1/ ビューで、ユーザー入力の検証/サニタイズ/変換用のフォームを使用してから、サニタイズ/変換されたデータを無視し、サニタイズされていない入力をリクエストから直接取得します。request.POST の代わりに form.cleaned_data を使用してデータを取得するか、完全に入力された Foo インスタンスを作成する ModelForm を使用することをお勧めします。

2/ Python メソッドには暗黙的な「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 関連のオブジェクトに基づいて何かを計算するのに適切な場所ではありません。計算を実行し、Foo を更新し、それを保存して、m2m が保存された後に呼び出す個別のメソッドを作成するか (ヒント: ModelForm が m2m 関連オブジェクトの保存を処理します)、または単に m2m_changed シグナルを使用します。

そうは言っても、Python と Django の学習に数時間費やすことを強くお勧めします。これにより、多くの時間を節約できます。

于 2012-06-29T08:09:14.443 に答える
0

多対多の代わりに「OneToOneField」を使用しない理由

于 2012-06-29T02:47:30.647 に答える