我如何从一个端点(尤其是棉花糖和SQLAlchemy)取回数据时遇到一些问题
https://gist.github.com/martinmckenna/eb5eeee5869663fc8f2e52a5e7ef72c9
我在鸡尾酒和配料之间有着多对多的关系,但是我不仅拥有关系表上的外键ings_in_cocktail的数据还多,例如ounces.
,当我得到/cocktails/
时,它返回如下内容:
{
"cocktails": [
{
"glass": "rocks",
"ingredients": [
{
"ingredient": {
"ing_type": "liquor",
"id": 1,
"name": "gin"
},
"ounces": 20
}
],
"finish": "stirred",
"id": 1,
"name": "gin and tonic"
}
]
}
我想做的是将ounces
属性的传播与ingredient
字典结合起来。
我希望数据如下所示:
{
"cocktails": [
{
"glass": "rocks",
"ingredients": [
{
"ing_type": "liquor",
"id": 1,
"name": "gin",
"ounces": 20
}
],
"finish": "stirred",
"id": 1,
"name": "gin and tonic"
}
]
}
在网上搜索了几个小时之后,我找不到使用Marshamallow轻松实现此目的的方法。有什么简单的方法我想念吗?
答案 0 :(得分:1)
您可以使用IngredientSchema
https://marshmallow.readthedocs.io/en/3.0/custom_fields.html#method-fields
请检查它如何在文档中使用此字段
答案 1 :(得分:0)
我最终解决了这个问题:
class CocktailSchema(ma.ModelSchema):
# this is responsible for returning all the ingredient data on the cocktail
ingredients = ma.Nested(CocktailIngredientSchema, many=True, strict=True)
ingredients = fields.Method('concat_ingredients_dicts')
"""
at this point the ingredients field on the cocktail object looks something like this
ingredients: [{
ingredient: {
name: 'white russian',
glass: 'rocks',
finish: 'stirred'
},
ounces: 2,
action: 'muddle',
step: 1
}]
what we want is to concat this data so "ingredients" just turns
into an list of dicts
"""
def concat_ingredients_dicts(self, obj):
result_ingredients_list = []
i = 0
while i < len(list(obj.ingredients)):
# create a dict from the fields that live in the relational table
relational_fields_dict = {
'ounces': obj.ingredients[i].ounces,
'action': obj.ingredients[i].action,
'step': obj.ingredients[i].step
}
# create a dict from the fields on each ingredient in the cocktail
ingredients_dict = obj.ingredients[i].ingredient.__dict__
ingredients_dict_extracted_values = {
'name': ingredients_dict.get('name'),
'type': ingredients_dict.get('ing_type'),
'id': ingredients_dict.get('id')
}
# merge the two dicts together
merged = dict()
merged.update(ingredients_dict_extracted_values)
merged.update(relational_fields_dict)
# append this merged dict a result array
result_ingredients_list.append(merged)
i += 1
# return the array of ingredients
return result_ingredients_list
class Meta:
model = Cocktail
答案 2 :(得分:0)
更新:我在底部放了一个更好的解决方案。
您可以通过使用Method
或Function
字段来实现此目的,以允许父级从子级获取数据。这是您需要做的:
CocktailSchema
。 IngredientSchema
(除非您还需要其他东西)。CocktailIngredientSchema
内,用几个Nested
字段替换Function
字段,这些字段将数据直接从内部“成分”对象中拉出。之前的模式
class IngredientSchema(ma.ModelSchema):
class Meta:
model = Ingredient
class CocktailIngredientSchema(ma.ModelSchema):
ingredient = ma.Nested(IngredientSchema)
class Meta:
model = CocktailIngredient
class CocktailSchema(ma.ModelSchema):
ingredients = ma.Nested(CocktailIngredientSchema, many=True)
class Meta:
model = Cocktail
之后的模式
class CocktailIngredientSchema(ma.ModelSchema):
ing_type = ma.Function(lambda obj: obj.ingredient.ing_type)
id = ma.Function(lambda obj: obj.ingredient.id)
name = ma.Function(lambda obj: obj.ingredient.name)
class Meta:
model = CocktailIngredient
class CocktailSchema(ma.ModelSchema):
ingredients = ma.Nested(CocktailIngredientSchema, many=True)
class Meta:
model = Cocktail
CocktailSchema
。 IngredientSchema
(而不是如上所示摆脱它)。CocktailIngredientSchema
内,用几个Nested
字段替换Pluck
字段,这些字段将数据直接从内部架构中拉出。之后的模式
class IngredientSchema(ma.ModelSchema):
class Meta:
model = Ingredient
class CocktailIngredientSchema(ma.ModelSchema):
ing_type = ma.Pluck(IngredientSchema, 'ing_type')
id = ma.Pluck(IngredientSchema, 'id')
name = ma.Pluck(IngredientSchema, 'name')
class Meta:
model = CocktailIngredient
class CocktailSchema(ma.ModelSchema):
ingredients = ma.Nested(CocktailIngredientSchema, many=True)
class Meta:
model = Cocktail