bha*_*ing 5 django many-to-many factory-boy
我在使用直通关系与工厂男孩中的一组Django模型建立多对多关系时遇到问题。我有一堆食谱和原料。通过设置数量的模型,配方和配料之间存在多对多关系。我有每种模型的工厂,但无法让它们链接起来。
简化的model.py:
class Ingredient(models.Model):
name = models.CharField(max_length=40)
class Recipe(models.Model):
name = models.CharField(max_length=128)
ingredients = models.ManyToManyField(Ingredient, through='RecipeIngredient')
class RecipeIngredient(models.Model):
recipe = models.ForeignKey(Recipe)
ingredient = models.ForeignKey(Ingredient)
quantity = models.IntegerField(default=1)
Run Code Online (Sandbox Code Playgroud)
简化的factory.py
class RecipeFactory(factory.django.DjangoModelFactory):
class Meta:
model = Recipe
class IngredientFactory(factory.django.DjangoModelFactory):
class Meta:
model = Ingredient
class RecipeIngredientFactory(factory.django.DjangoModelFactory):
class Meta:
model = RecipeIngredient
recipe = factory.SubFactory(RecipeFactory)
ingredient = factory.SubFactory(IngredientFactory)
quantity = 1
Run Code Online (Sandbox Code Playgroud)
我试过弄乱factory.RelatedFactory,但还没到什么地方。理想情况下,我只希望能够执行以下操作:
recipe = RecipeFactory(name="recipe1")
ingredient = IngredientFactory(name="ingredient1")
ri = RecipeIngredientFactory(recipe=recipe, ingredient=ingredient)
Run Code Online (Sandbox Code Playgroud)
这样做虽然不会在任何一方设置多对多关系,而且似乎也无法创建配方配料模型本身。有人知道这样做的方法吗?
编辑:
我也尝试过:
class RecipeWith3Ingredients(RecipeFactory):
ingredient1 = factory.RelatedFactory(RecipeIngredientFactory, 'recipe')
ingredient2 = factory.RelatedFactory(RecipeIngredientFactory, 'recipe')
ingredient3 = factory.RelatedFactory(RecipeIngredientFactory, 'recipe')
Run Code Online (Sandbox Code Playgroud)
但是我无法理解如何使用预先存在的配方和成分来创建这些对象。
我刚刚重新创建了此设置,但正在努力查看问题出在哪里。这里有几项测试证明一切似乎都正常运行?还是我误会了这个问题?
# create recipe ingredient and recipe ingredient
recipe = RecipeFactory(name="recipe1")
ingredient = IngredientFactory(name="ingredient1")
recipe_ingredient = RecipeIngredientFactory(recipe=recipe, ingredient=ingredient)
# recipe created?
r = Recipe.objects.all().first()
self.assertEqual(r, recipe)
# ingredient created?
i = Ingredient.objects.all().first()
self.assertEqual(i, ingredient)
# recipe ingredient created?
ri = RecipeIngredient.objects.all().first()
self.assertEqual(ri, recipe_ingredient)
# test many to many
self.assertEqual(ri, r.recipeingredient_set.all()[0])
self.assertEqual(ri, i.recipeingredient_set.all()[0])
# add a new ingredient to recipe 1
ingredient2 = IngredientFactory(name='ingredient2')
recipe_ingredient2 = RecipeIngredientFactory(recipe=recipe, ingredient=ingredient2)
# test many to many
self.assertTrue(recipe_ingredient in r.recipeingredient_set.all())
self.assertTrue(recipe_ingredient2 in r.recipeingredient_set.all())
# create a pre-existing recipe and a set of ingredients
pizza_recipe = RecipeFactory(name='Pizza')
cheese_on_toast_recipe = RecipeFactory(name='Cheese on toast')
cheese_ingredient = IngredientFactory(name='Cheese')
tomato_ingredient = IngredientFactory(name='Tomato')
pizza_base_ingredient = IngredientFactory(name='Pizza base')
toast_ingredient = IngredientFactory(name='Toast')
# now put together
RecipeIngredientFactory(recipe=pizza_recipe, ingredient=cheese_ingredient)
RecipeIngredientFactory(recipe=pizza_recipe, ingredient=tomato_ingredient)
RecipeIngredientFactory(recipe=pizza_recipe, ingredient=pizza_base_ingredient)
RecipeIngredientFactory(recipe=cheese_on_toast_recipe, ingredient=cheese_ingredient)
RecipeIngredientFactory(recipe=cheese_on_toast_recipe, ingredient=toast_ingredient)
# test pizza recipe
pizza_ingredients = [cheese_ingredient, tomato_ingredient, pizza_base_ingredient]
pr = Recipe.objects.get(name='Pizza')
for recipe_ingredient in pr.recipeingredient_set.all():
self.assertTrue(recipe_ingredient.ingredient in pizza_ingredients)
# test cheese on toast recipe
cheese_on_toast_ingredients = [cheese_ingredient, toast_ingredient]
cotr = Recipe.objects.get(name='Cheese on toast')
for recipe_ingredient in cotr.recipeingredient_set.all():
self.assertTrue(recipe_ingredient.ingredient in cheese_on_toast_ingredients)
# test from ingredients side
cheese_recipes = [pizza_recipe, cheese_on_toast_recipe]
ci = Ingredient.objects.get(name='Cheese')
for recipe_ingredient in ci.recipeingredient_set.all():
self.assertTrue(recipe_ingredient.recipe in cheese_recipes)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1162 次 |
| 最近记录: |