Python Django遍历关系
我有一些模型,它们之间的关系如下:Python Django遍历关系,python,django,Python,Django,我有一些模型,它们之间的关系如下: class Conversion(models.Model): class Unit(models.IntegerChoices): g = 10, 'gramy', ml = 20, 'mililitry', qty = 30, 'sztuki' name = models.CharField(max_length=128) g = models.FloatField()
class Conversion(models.Model):
class Unit(models.IntegerChoices):
g = 10, 'gramy',
ml = 20, 'mililitry',
qty = 30, 'sztuki'
name = models.CharField(max_length=128)
g = models.FloatField()
ml = models.FloatField(null=True, blank=True)
qty = models.FloatField(null=True, blank=True)
default = models.IntegerField(choices=Unit.choices, default=Unit.g)
class Ingredient(models.Model):
class Unit(models.IntegerChoices):
g = 10, 'gramy',
dkg = 11, 'dekagramy',
kg = 12, 'kilogramy',
ml = 20, 'mililitry',
l = 21, 'litry',
qty = 30, 'sztuki'
Conversion = models.ForeignKey(Conversion, on_delete=models.CASCADE, related_name='ingredients')
amount = models.FloatField()
unit = models.IntegerField(choices=Unit.choices, default=Unit.g)
class Step(models.Model):
body = models.JSONField()
Ingredients = models.ManyToManyField(Ingredient, related_name='steps')
class Recipe(models.Model):
title = models.CharField(max_length=128)
teaser = models.CharField(max_length=256)
Steps = models.ManyToManyField(Step, blank=True, related_name='recipes')
假设面粉有一个转换,其中1ml==.53g,步骤是分开的,因为它们是如何显示的,所以我认为最好把它们都放在不同的模型中
现在,如果一个用户告诉我他有一些数量(配料。数量)的配料(转换),我想找到所有的食谱有相等或更少的这些
例如,用户选择3个入口:
|换算.pk |金额|
|-------------|------|
|1 |200 |
|2 |300 |
|3 | 1000|
如果一个食谱有步骤1和步骤2,数量合适,但没有第三个步骤,我也想找到它。如果我正确理解了这一点,我可能没有,我想你是在为每个步骤添加配料。配料有一个数量和单位以及一个转换,该转换将配料名称与基本数量和单位一起存储。我在理解上有点不对劲的地方是知道成分、数量、转化率和数量之间的区别。Conversion.g和Conversion.ml是Conversion.default到该单位的换算系数吗 在任何情况下,我认为您都希望将步骤作为多对多字段移出配方,并在步骤到配方中添加外键。从风格上看,我还建议您将所有字段命名为小写(因此Step.contracents变为Step.contracents),因为这将使以后的生活更简单,始终知道您是在查看类还是属性 我也不相信你想要的配料是多对多的,因为你的数量与配料有关。这意味着,如果你有一个指向1杯面粉的配方,而你后来又有了另一个使用相同记录的配方,但决定将其更改为3/4杯面粉,那么你原来的配方将接受该更改。我相信您希望在步骤中使用外键(但我没有在下面进行更改) 以下是我建议的起点(但我认为成分不应该是步骤中的多对多) 一些管理员只是为了好玩
from django.contrib import admin
from recipe_15285278.models import Recipe, Ingredient, Step, Conversion
@admin.register(Step)
class StepAdmin(admin.ModelAdmin):
pass
class StepInline(admin.TabularInline):
model = Step
@admin.register(Recipe)
class RecipeAdmin(admin.ModelAdmin):
pass
inlines = [StepInline, ]
@admin.register(Ingredient)
class IngredientAdmin(admin.ModelAdmin):
pass
@admin.register(Conversion)
class ConversionAdmin(admin.ModelAdmin):
pass
我不相信这是适合您尝试构建的体系结构,但如果是,您可以从这里开始构建查询。我已经将步骤更改为TextField
,因为我使用的sqllite不支持JSONField
我觉得这可能是你考虑取消标准化模型并建立一组字段来保持计算量的时间之一。因此,如果在创建时需要25毫升的东西,你对所有其他单位进行计算,然后存储在适当的字段中。这样做的好处是以后搜索/过滤更快更容易,因为您不必每次需要时都重新计算。如果您不喜欢术语“反规范化”,请将其视为缓存结果。@AMG您在这里有一个观点,过滤它会容易得多,但这样我就无法用各种成分填充转换,用户必须手动键入名称,并在每个步骤中配置每个成分的转换。使用之前在每次搜索中要执行的相同转换方法,使该部分自动。也许我误解了工作流程。我的建议可能是转换已经是什么?转换是一种特定类型的成分(由于py内置,不想将其命名为类型)。例如,可以有一个名为面粉的转换,g=0.53,ml=1。所有单位应彼此相等。在这个例子中,1毫升面粉=0.53克。这意味着我们可以看看别人做的食谱,如果你需要,你可以转换测量单位。配料是一个包装,上面写着:配料类型+该类型默认单位的数量+它在配方中的显示方式。配方需要1000克面粉,所以只需以千克为单位显示即可。转换对象存储配料中每种类型的名称和默认计量单位。例如,面粉,默认单位为克或水,默认单位为毫升。所有其他字段彼此对应,作为相同数量的成分,但单位不同。对于水,你可以放1g=1ml或10g=10ml。对于面粉,你可以说53g=100ml。我真的很喜欢你的编辑,你说M2M不是最好的配料选择是对的。此外,conversion.qty是为樱桃番茄等配料保留的(也需要克,因此所有东西都可以转换为重量)。您制作的模型非常适合我的需要,但我如何搜索用户可以使用他们拥有的给定配料制作的食谱。例如,当我有足够的黄油和面包,但也有(比如)100克西红柿时,如何在管理面板中找到你制作的配方?是的,我认为转换需要重命名为配料,步骤不应包含配料(它们应属于配方而不是步骤),应该有一个完整的配方配料表,其中包含该配方的数量。这有意义吗?将在时间允许的情况下编辑答案。由于编辑器的工作方式和所有内容的显示方式,成分分为多个步骤。用户应该能够单独查看每个步骤。编辑器看起来有点像:konopka.me/editor(它的显示方式也是这样:)。我也在考虑在提交时对每个食谱进行后期处理,这样它就有了自己的配料表。这可能是最好的选择,因为每一步都可能含有一定量的相同成分。搜索也会容易得多。
from django.contrib import admin
from recipe_15285278.models import Recipe, Ingredient, Step, Conversion
@admin.register(Step)
class StepAdmin(admin.ModelAdmin):
pass
class StepInline(admin.TabularInline):
model = Step
@admin.register(Recipe)
class RecipeAdmin(admin.ModelAdmin):
pass
inlines = [StepInline, ]
@admin.register(Ingredient)
class IngredientAdmin(admin.ModelAdmin):
pass
@admin.register(Conversion)
class ConversionAdmin(admin.ModelAdmin):
pass