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'实例需要有一个主键值才能使用多对多关系。”

我使用 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,
    }))

PS我发现我失败了。它在模型中。我在保存方法中使用了多对多。我在使用前添加了检查,但这没有帮助。

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

这对我有帮助,但我不认为这是 django 的方式。有趣的是,没有这个检查管理面板显示错误,而是创建对象。现在,如果我从两个中选择项目并保存,我的对象没有 full_cost,但是当我查看我的对象时,管理面板会记住我的选择并向我显示我的两个项目,我选择了什么......我不知道为什么。

我该如何保存?

4

2 回答 2

0

为什么不使用“OneToOneField”而不是多对多

于 2012-06-29T02:47:30.647 回答
0

你的代码有很多问题。最明显的是

1/ 在您看来,使用表单进行用户输入验证/清理/转换,然后忽略经过清理/转换的数据并直接从请求中获取未经清理的输入。使用 form.cleaned_data 而不是 request.POST 来获取您的数据,或者更好地使用 ModelForm 它将为您创建一个完全填充的 Foo 实例。

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 相关对象计算 someting 的正确位置。要么编写一个独特的方法来运行计算并更新 Foo 并保存它并在保存 m2m 后调用它(提示:ModelForm 将负责为您保存 m2m 相关对象),或者只使用 m2m_changed 信号。

话虽这么说,我强烈建议你花几个小时学习 Python 和 Django——它会为你节省很多时间。

于 2012-06-29T08:09:14.443 回答