django复杂模型和模板

发布于 2024-09-03 19:43:56 字数 1423 浏览 9 评论 0原文

我使用“通过”的多对多关系重塑我的对象,如下所示: 链接文本

class Receipt(models.Model):
  name = models.CharField(max_length=128)
  (...)
  components = models.ManyToManyField(Product, through='ReceiptComponent')
  class Admin:
    pass

  def __unicode__(self):
    return self.name

  def url(self):
    return self.id

class ReceiptComponent(models.Model):
  product = models.ForeignKey(Product)
  receipt = models.ForeignKey(Receipt)
  quantity = models.FloatField(max_length=9)
  unit = models.ForeignKey(Unit)
  class Admin:
    pass
  def __unicode__(self):
    return unicode(self.quantity!=0 and self.quantity or '') + ' ' + unicode(self.unit) + ' ' + self.product.genitive

看起来不错,但我有它有两个问题:

1)在管理员管理面板中,与收据没有简单的连接=如果我必须添加一个新组件 - 我应该转到组件并使组件连接到收据 - 也许这是唯一的解决方案 - 但它会更多收据直观

2)我无法使用模板打印它:

views.py:

(...)
def detail(request, receipt_id):
    receipt = get_object_or_404(Receipt, pk=receipt_id)
    components = receipt.components.all()
    return render_to_response('receipt.html',{'receipt' : receipt, 'components' : components,}
(...)

receipt.html:

<h1>{{ receipt.name }}</h1>
{% for component in components.all %}
<div class='component'>{{ component }}</div>
{% endfor %}

I remodel my objects using ManyToMany relationship using "through" as it's guided here:
link text

class Receipt(models.Model):
  name = models.CharField(max_length=128)
  (...)
  components = models.ManyToManyField(Product, through='ReceiptComponent')
  class Admin:
    pass

  def __unicode__(self):
    return self.name

  def url(self):
    return self.id

class ReceiptComponent(models.Model):
  product = models.ForeignKey(Product)
  receipt = models.ForeignKey(Receipt)
  quantity = models.FloatField(max_length=9)
  unit = models.ForeignKey(Unit)
  class Admin:
    pass
  def __unicode__(self):
    return unicode(self.quantity!=0 and self.quantity or '') + ' ' + unicode(self.unit) + ' ' + self.product.genitive

It looks ok, but I have 2 problems with it:

1) In admin management panel there's no easy connection with receipt = If I have to add a new component - I should go to components and make component connected to receipt - maybe it's the only solution - but it would be more intuitive in receipts

2) I can't print it using templates:

views.py:

(...)
def detail(request, receipt_id):
    receipt = get_object_or_404(Receipt, pk=receipt_id)
    components = receipt.components.all()
    return render_to_response('receipt.html',{'receipt' : receipt, 'components' : components,}
(...)

receipt.html:

<h1>{{ receipt.name }}</h1>
{% for component in components.all %}
<div class='component'>{{ component }}</div>
{% endfor %}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

玩世 2024-09-10 19:43:56

你对 .all 所做的正是我的意思——你最初将它放在两个地方,视图中的 .all() 和模板中的 .all。

您的“错误”原因非常明显 - 组件是 Product 的 m2m 字段。这就是你在代码中写的。该组件是产品集,而不是中间模型ReceiptComponent。

UPD:只需将模型保留原样,然后使用 Receipt 中的 receiptcomponent_set

What you did with .all is exactly what I meant -- you had it initially in 2 places, .all() in view and .all in template.

The reason of your 'error' is quite evident - components is the m2m field to Product. This is what your wrote in your code. This components is the set of products, not intermediary model ReceiptComponent.

UPD: simply leave your models as are, and use receiptcomponent_set from the Receipt

后eg是否自 2024-09-10 19:43:56

1)您尝试过内联吗?

2)删除模板中的 .all ,您不需要它。
也许你还需要
组件 = 列表(receipt.components.all())

1) Have you tried inlines?

2) remove .all in your template, you don't need it.
May be you will also need
components = list(receipt.components.all())

浮世清欢 2024-09-10 19:43:56

1)看起来很完美! (给其他用户的提示:inline != inlines ;D

2)删除 .all 会导致异常:

Caught an exception while rendering: 'ManyRelatedManager' object is not iterable

但我知道,为了获得高质量的代码,我应该将其从模板移动到代码:

views.py:

def detail(request, receipt_id):
  receipt = get_object_or_404(Receipt, pk=receipt_id)
  components = receipt.components.all()
  additionals = receipt.additionals.all()

  return render_to_response('drinkbook/receipts/receipt.html',{'receipt' : receipt, 'components' : components, 'additionals' : additionals, })

template:

h1>{{ receipt.name }}</h1>
{% for component in components %}
<div class='component'>{{ component }}</div>
{% endfor %}
{% if receipt.additionals %}Ponadto:
{% for additional in additionals %}
<div class='additional'>{{ additional }}</div>
{% endfor %}
{% endif %}
<p>{{ receipt.desc|safe }}</p>

Ok。它现在可以工作,但组件的结果是 Product.unicode 而不是 ReceiptComponent.unicode (它是 Product 的子级)。为什么?

1) looks perfect! (hint for other users: inline != inlines ;D

2) removing .all causes an exception:

Caught an exception while rendering: 'ManyRelatedManager' object is not iterable

but I understand that for good quality code I should move it from template to code:

views.py:

def detail(request, receipt_id):
  receipt = get_object_or_404(Receipt, pk=receipt_id)
  components = receipt.components.all()
  additionals = receipt.additionals.all()

  return render_to_response('drinkbook/receipts/receipt.html',{'receipt' : receipt, 'components' : components, 'additionals' : additionals, })

template:

h1>{{ receipt.name }}</h1>
{% for component in components %}
<div class='component'>{{ component }}</div>
{% endfor %}
{% if receipt.additionals %}Ponadto:
{% for additional in additionals %}
<div class='additional'>{{ additional }}</div>
{% endfor %}
{% endif %}
<p>{{ receipt.desc|safe }}</p>

Ok. It works now, but the result of component is Product.unicode not ReceiptComponent.unicode (which is a child of Product). Why?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文