【问题标题】:Access to models with a foreign key in the template使用模板中的外键访问模型
【发布时间】:2016-06-14 10:20:43
【问题描述】:

我有一个profile 模型与User 模型具有一对一的关系,因此我可以访问模板罐中的两个模型到user 变量,如下所示:

template.html

{% if user.profile.phone == 1234567890 %}
    Show something
{% endif %}

效果很好,条件给出了True 并显示了一些东西,但我也有PropertyUser_Property 的模型,User_Property 模型具有Foreignkey 来自UserProperty 的ID .

models.py

class Property(models.Model):
    name = models.CharField(max_length=50, unique=True)

class User_Property(models.Model):
    us = models.ForeignKey(User, related_name='up_us')
    prop = models.ForeignKey(Property, related_name='up_prop')

所以如果我尝试像这样访问User_Property 模型:

{% if user.user_property.prop == 1 %}
    Show something
{% endif %}

我无法访问它,即使它是 True,我也没有尝试过 False。这是因为与Profile 模型的关系是用OneToOneField 建立的,而与User_Property 的关系是用ForeignKey 字段建立的,我需要将context 传递给User_Property 模型?

如果我在模板中使用JOIN SQL 语句,是否可以访问Property 模型?像这样:

{% if user.user_property.property.name == 'the name of the property' %}
    Show something
{% endif %}

抱歉,帖子太长了,但我尝试添加所有需要的信息。

编辑:好的,如果有人需要类似的东西,这就是我为解决问题所做的。

创建一个context_processor.py 以返回一个User_Property 的实例并将其添加到我的settings.py 中,这样即使我没有在视图中将它作为上下文传递,我也可以在我的所有模板中访问该实例.

context_processors.py

from App_name.models import User_Property
from django.contrib.auth.models import User

def access_prop(request):
    user = request.user.id #add the .id to no have problems with the AnonymousUser in my logg-in page
    user_property = User_Property.objects.filter(us=user).values_list('prop', flat=True) #this stores the list of all the properties for the logg-in user
    return {
        'user_property': user_property,
    }

settings.py

from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_CONTEXT_PROCESSORS += ('App_name.context_processors.access_prop',)

然后在模板中检查用户是否具有特定属性

template.html

{% if 'property name' in user_property %}
    Show something
{% else %}
    This is not for you
{% endif %}

要检查name 而不是id 的具体情况,只需在我的模型User_Property 的prop 字段中添加to_field='name',如下所示:prop = models.ForeignKey(Property, related_name='up_prop', to_field='name')

【问题讨论】:

  • 很难跟上。您是否有OneToOneField 关系?你将什么作为user 传递给上下文?
  • OneToOneField 关系在UserProfile 模型之间,user 是来自当前登录用户docs.djangoproject.com/en/1.8/topics/auth/default/#usersUser 模型的一个实例跨度>
  • 还有一条建议,最好不要将您的班级命名为Property,它是保留名称(小写)。
  • @vishes_shell 别担心,这只是我在这个例子中使用的名字,而不是我在课堂上使用的真实名字。

标签: python html django django-models django-templates


【解决方案1】:

来自docs

您应该使用您在ForeignKey 中设置的related_name 和关系的内置方法:

试试这个:

user.up_us.filter(prop__name="the name")

编辑

要使用.filter(prop__name="the name") 方法,您必须在.py 文件中进行。

【讨论】:

  • 给我TemplateSyntaxError Could not parse the remainder: '(prop__name="the name")' from 'user.up_us.filter(prop__name="the name")'
  • 在views.py中做,并在上下文中传递。
  • 如果我应用条件的元素来自我的 base.html 模板并且不使用视图传递上下文,我可以这样做吗?
  • 当然,看看 django 中的上下文处理器 -> docs
  • 感谢@arcegk,刚刚创建了我自己的 context_processor 以访问我的 base.html 中的 User_Property 实例
【解决方案2】:

试试看:{% if user.user_property.prop.id == 1 %}

【讨论】:

  • @M.Gar 试试 printin {{user.user_property}} 我觉得这没什么价值。
  • @M.Gar 你需要使用up_us,因为这是反向关系。
  • ok,使用 {{user.up_us}} 向我展示了 App.User_Property.None,我认为这表明现在可以访问该模型。
  • @M.Gar 是的,但请记住,可能有许多 User_Property 对象指向同一个 User 对象,因此当您调用 user.up_us 时,它会给您一个集合而不是对象,您可以使用 request.user.up_us.all() 在您的视图中测试它
  • @M.Gar 您可以在您的视图中选择User_Property 并将其发送到视图:request.user.up_us.get(pk=1) 这将提供带有id=1User_Property 对象,将其添加到您的上下文中并在您的模板中使用它。
【解决方案3】:

你已经在us = models.ForeignKey(User, related_name='up_us')中设置了related_name,所以你需要使用它

{% if user.up_us.prop.name == 'the name of the property' %}
    Show something
{% endif %}

这个answer 很好地解释了如何使用以及related_name 的用途。

并尝试从模板中排除大量逻辑。

【讨论】:

  • 尝试使用related_name,但没有任何效果
  • @M.Gar 你可以尝试在你的视图print(request.user.up_us.prop.name)。因为我认为这不可能以其他方式起作用。确保您的用户已通过身份验证,并且存在与当前用户相关的 User_Property,并且需要 prop 和所需的 name
猜你喜欢
  • 2015-01-16
  • 2013-07-10
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 1970-01-01
  • 2019-11-10
  • 2013-06-01
相关资源
最近更新 更多