【问题标题】:DJANGO MODELS, use one class objects in another class (ManyToManyField) (?)DJANGO 模型,在另一个类中使用一个类对象(ManyToManyField)(?)
【发布时间】:2018-10-16 01:51:45
【问题描述】:

我想在另一个类中使用一个类对象。

我想要实现的目标: 我已经创建了一些成分对象,例如“鸡肉”、“米饭”等。 每个都有自己的卡路里、蛋白质等。 现在我想根据这些成分创建膳食并计算卡路里汇总。

我的目标: 1. 创建餐点: sample_dinner = Meal(name='sample_dinner',ing1='鸡',ing2='rise',ing3='tomato') 2.计算卡路里,函数很容易写但是我需要先传args 3. 在视图中显示它们(我知道如何)

models.py

class Ingredient(models.Model):
    name = models.CharField(max_length=20,default='')
    calories = models.PositiveIntegerField(default=0)
    proteins = models.PositiveIntegerField(default=0)
    carbs = models.PositiveIntegerField(default=0)
    fat = models.PositiveIntegerField(default=0)

class Meal(models.Model):
    name = models.CharField(max_length=100,default='')
    ingredientone = models.ManyToManyField(Ingredient)

    calories_value = calc_nut_value()

    def calc_nut_value():
        ingr1 = Ingredient.objects.get(name=(f.e 'chicken'))
        ingr2 = Ingredient.objects.get(name=(f.e 'rice'))
        ingr3 = Ingredient.objects.get(name=(f.e 'tomato'))
        calories = ingr1.calories + ingr2.calories + ingr3.calories 
        return calories

【问题讨论】:

  • 为什么要传递参数?从所有成分而不是只计算鸡肉中计算卡路里值更有意义
  • 我有一整桌的配料,不仅是为了这顿特别的饭菜,也是为了我将来要创造的所有食物。 f.e.我不想把鸡肉放在我的早餐麦片里……所以我只想要精选的
  • 但是如果你想计算鸡肉的卡路里,为什么你在 Meal 模型中有卡路里值。它应该在成分类中。没看懂,你有一个班级Meal(一顿饭可以有很多配料)你在这个班级里只计算一种配料的calories_value?
  • 我刚刚编辑了代码以使其更清晰。
  • 而且 calc_nut_value 中的所有成分都与特定餐点有关?因为您不需要选择特定的食材,您可以选择与特定餐点相关的所有食材。这对我来说很有意义

标签: python django python-3.x django-models


【解决方案1】:

好的,所以答案比我说的要难得多。我真的很抱歉。这是因为ManyToMany relation 保存在保存方法之外,并且您无法在覆盖的保存方法中计算值,因为我们无法在那里获取成分。我在你的模型上测试了我的代码,它可以工作。但是你必须创建signal

每次创建或更改 ManyToMany 关系时都会调用 M2M_changed 信号。在此信号中,您可以从 ManyToMany 关系计算值。您可以通过模型中的参数获取关系。

首先你必须在 signals.py 文件中创建信号:

from .models import Meal
from django.db.models.signals import m2m_changed
from django.dispatch import receiver


@receiver(m2m_changed, sender=Meal.ingredientone.through)
def calc_calories(sender, instance, action, **kwargs):
    # you can get all ingredients for meal
    ingrs = instance.ingredientone.all()

    # iterate over ingredients
    calories = 0
    for ingr in ingrs:
        calories += ingr.calories
    instance.calories_value = calories
    instance.save()

然后您必须在 apps.py(在 AppConfig 中)中导入您的信号。您必须在 settings.py 中的 INSTALLED_APPS 中使用此配置,但我认为在较新版本的 Django 中这是一种标准方式:

from django.apps import AppConfig


class AppNameConfig(AppConfig):
    name = 'appname'

    def ready(self):
        import appname.signals

此代码运行良好,如果您还有其他问题。请不要犹豫,问我。

【讨论】:

    猜你喜欢
    • 2017-08-16
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多