2012-06-29 59 views
0

例如。多对多关系中的Django管理员错误

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.S.我发现我的失败。它在模型中。我在保存方法中使用了多对多。我在使用前添加检查,但这没有帮助。

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的方式。有趣的是,没有这个检查管理面板显示错误,但创建对象。现在,如果我从Two中选择项目并保存,我的对象没有full_cost,但是当我查看我的对象时,管理面板记住我的选择并向我显示我的两个项目,我选择了......我不知道为什么。

我该如何保存?

回答

0

有相当与您的代码的几个问题。最显而易见的是在用户输入验证/消毒/转换时使用表单,然后忽略已处理/转换后的数据并直接从请求中获取未经处理的输入。使用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相关对象来计算成才的正确的地方。或者编写一个运行计算的独特方法并更新Foo并保存并在m2m保存后调用它(提示:ModelForm将负责为您保存m2m相关对象),或者仅使用m2m_changed信号。

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

+0

非常感谢。后来我改变我的代码,以正确的形式白色“自我”,但我忘了更新这篇文章。感谢您对form.cleaned_data和form.save的建议,我会用这个)我只是复制\粘贴相同的代码,并使用他*( 那么m2m。你告诉写方法,会做什么更新,保存等。你可以显示一个例子或链接,我可以阅读关于这个? m2m_changed信号怎么样 - 谢谢。也许我在我的解决方案中使用它。 –

+0

在文档中有相当多的代码示例和解释,您应该先阅读它。 –

0

为什么不使用“OneToOneField”,而不是多到许多

+0

如何在使用订单和产品时使用OneToOne?一个订单有很多产品,一个产品可以有很多订单。 –

+0

哦。不知道你的代码还有更多。下次导入整个型号代码:P –