Django:将一个应用程序分成多个:模板,代理模型和ForeignKeys

时间:2017-05-31 04:13:25

标签: python django

为了让我的项目更清洁,我决定(可能是错误的)将我的一个Django应用程序分成两部分。一个用于管理信息的应用程序,另一个用于显示。为此,我认为在显示应用程序中使用Django代理模型将是最好的方法。但是,我在某些模型中遇到了ForeignKey字段的问题,并强制这些外键使用代理模型,而不是其原始模型。

以下是一些让它更清晰的例子:

App_1-model.py

class Recipe(models.Model):
    name = models.CharField(max_length=200)
    slug = models.SlugField()
    ...

class Ingredient(models.Model):
    name = models.CharField(max_length=200)
    recipe = models.ForeignKey(Recipe)
    weight = models.IntegerField()

App_2-model.py(导入App_1型号)

class RecipeDisplayProxy(Recipe):

    class Meta:
        proxy = True

    @property
    def total_weight(self):
        # routine to calculate total weight
        return '100g'


class IngredientDisplayProxy(Ingredient):

    class Meta:
        proxy = True

    @property
    def weight_lbs(self):
        # routine to convert the original weight (grams) to lbs 
        return '2lb'

App_2.views.py

def display_recipe(request, slug):
    recipe = get_object_or_404(RecipeDisplayProxy, slug=slug)

    return render(
        request,
        'display_recipe/recipe.html',
        {'recipe': recipe}
        )

APP_2-template.html

<h2 class="display-4">{{ recipe.name }}</h2>
<p>{{ recipe.total_weight }}</p> <!-- This works fine, as expected //-->

<ul>
{% for recipe_ingredient in recipe.ingredient_set.all %}
<li>{{recipe_ingredient.ingredient}} &ndash;

{{recipe_ingredient.weight_lbs}}</li>

<!-- 
The above line doesn't return anything as the 'Ingredient' model, not the "IngredientDisplayProxy' is being returned. (As expected) 
-->

{% endfor %}
</ul>

这里发生的是我成功返回视图中指定的RecipeDisplayProxy模型,但是当我访问ingredient_set时,它返回Ingredient模型,而不是IngredientDisplayProxy(如预期的那样)。

那么如何强制使用ingredient_set来返回IngredientDisplayProxy模型?

我尝试实现此处的代码: Django proxy model and ForeignKey

但没有运气。然后我开始深入研究RecipeDisplayProxy的 init ()方法 - 看看我是否可以覆盖在ingredient_set中使用的模型,但是找不到能给我正确响应的任何东西。< / p>

那么任何想法?

或者,我只是把它放在一条糟糕的道路上 - 而且应该完全考虑不同的设计?

2 个答案:

答案 0 :(得分:0)

从视图中返回配方实例,但是在模板中,您通过配方访问配料,但它应该是相反的,从您可以访问配方的配料。现在代理模型,更好阅读此documentation

答案 1 :(得分:0)

看起来我做错了什么,依据fips的建议我回去做了以下事情:

class RecipeDisplayProxy(Recipe):

    class Meta:
        proxy = True

    @property
    def total_weight(self):
        # routine to calculate total weight
        return '100g'

    @property
    def ingredient_set(self):
        qs = super(RecipeDisplayProxy, self).ingredient_set
        qs.model = IngredientDisplayProxy
        return qs

就是这么简单:'(谢谢你的帮助和建议。