【问题标题】:Django: unable to display iunformation using a TemplateView Class Based viewDjango:无法使用基于 TemplateView 类的视图显示信息
【发布时间】:2021-03-06 20:02:06
【问题描述】:

我正在使用基于类的视图 (TemplateView) 来显示来自用户和 UserProfile 模型(用户和 UserProfile 之间的一对一)的一些信息,这按预期工作。 我决定使用相同的 TemplateView 来显示来自 2 个模型的其他一些数据,但我不明白为什么我无法检索和显示信息。 我怀疑这是因为其中一个模型(UserSubscription)有 2 个 fks,一个是用户模型,另一个是“订阅”模型。 我尝试在 fks 中使用related_name,但不确定我是否正确使用它。 代码如下:

models.py

class UserSubscription(models.Model):
    user = models.ForeignKey(User, related_name= 'tousers', related_query_name='touser', on_delete=models.CASCADE, null=True, blank=True)
    subscription = models.ForeignKey("Subscription", related_name = 'tosubscriptions', related_query_name='tosubscription',on_delete=models.CASCADE, null=True, blank=True)
    created_date = models.DateTimeField(auto_now=True, auto_now_add=False, verbose_name="Created Date")
    subs_status = models.BooleanField(default=False, verbose_name="Subscription Status")
    expiry_date = models.DateTimeField(auto_now=False, auto_now_add=False, verbose_name="Expiry Date")
    

    class Meta:
        verbose_name = "User Subscription"
        verbose_name_plural = "User Subscriptions"

    def __str__(self):
        return 'User: ' + str(self.user) + ' ' + 'PK: ' + str(self.pk) + ' Subscription :' + str(self.subscription) + ' ' + 'Expiring the : ' +  str(self.expiry_date)

class Subscription(models.Model):
    plan_name = models.CharField(max_length=50, null=True, blank=True, verbose_name="Subscription Plan Name")    
    description = models.TextField(verbose_name="Subscription Plan Description")   
    price = models.FloatField(verbose_name="Subscription Plan Price")   
    start_date = models.DateTimeField(auto_now=False, auto_now_add=False, verbose_name="Subscription Plan Start Date")
    end_date = models.DateTimeField(auto_now=False, auto_now_add=False, verbose_name="Subscription Plan End Date")   
    active = models.BooleanField(default=False)         

    class Meta:
        verbose_name = "Subscription"
        verbose_name_plural = "Subscriptions"       

    def __str__(self):
        return self.plan_name

views.py

from django.shortcuts import render, redirect
from django.views.generic import TemplateView, UpdateView, ListView
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User

from .models import *
from .forms import *


class MyProfileView(TemplateView):
    template_name = 'myprofile.html'

    def get_context_data(self, **kwargs):
         context = super(MyProfileView, self).get_context_data(**kwargs)
         context['User'] = User.objects.all()
         context['UserProfile'] = UserProfile.objects.all()
         context['subscription'] = Subscription.objects.all()
         context['usersubscription'] = UserSubscription.objects.all()
         return context

myprofile.html

{% extends 'base.html' %}

{% block title %}
My Profile
{% endblock %}

{% block content %}
<p>Username: {{user.username}}</p>
<p>First Name: {{user.first_name}}</p>
<p>Last Name: {{user.last_name}}</p>
<p>Birth Date: {{user.userprofile.birth_date}}</p>
<p>Email: {{user.email}}</p>
<p>Language: {{user.userprofile.language}}</p>
<p>Address: {{user.userprofile.address}}</p>
<p>Postal Code: {{user.userprofile.postal_code}}</p>
<p>Country: {{user.userprofile.country}}</p>
<form action ='{% url "updatemyprofile" %}'>
<button type="submit">Update My Profile</button>
</form>
<hr>
<p>My Current Plan:{{usersubscription.subscription.plan_name}}</p>
<p>Start Date: {{usersubscription.created_date}}</p>
<p>End Date: {{usersubscription.expiry_date}}</p>
<p>Renew:</p>
<hr>

{% endblock  %}

urls.py

from django.urls import path

from . import views as gecviews

urlpatterns = [
    path('myprofile/', gecviews.MyProfileView.as_view(), name='myprofile'), 
    path('updatemyprofile/', gecviews.profileUpdate, name='updatemyprofile'), 

结果:

用户名:foo

名字:foo

姓氏:酒吧

出生日期:2020 年 2 月 2 日

电子邮件:foo@bar.com

语言:英文

地址:富吧大道

邮政编码:1000

国家:美国

我目前的计划:

开始日期:

结束日期:

续订:

【问题讨论】:

  • 您正在对每个返回查询集(多个对象)而不是单个对象的模型执行.objects.all()。因此,在您的模板中,您必须遍历查询集才能显示您的数据。

标签: django django-views django-templates


【解决方案1】:

这是因为您在 context['usersubscription'] 中拥有的是一个查询集。

在你的视野中尝试这个:

context['usersubscription'] = UserSubscription.objects.get(user=request.user)

或者您可以在模板中更改这些:

<p>My Current Plan:{{request.user.user_subscription.subscription.plan_name}}</p>
<p>Start Date: {{request.user.usersubscription.subscription.created}}</p>
<p>End Date: {{request.user.usersubscription.subscription.expiry_date}}</p>

编辑

{% with request.user.tousers|first as t %}
t.subscription.expiry_date
{% end with %}

【讨论】:

  • 在我看来,我已经完成了以下操作:UserSubscription.objects.filter(user=self.request.user) 并且我在模板中没有得到任何回报,尽管我确信用户“foo ”有一个“1年”的订阅。我也尝试过第二种方法(仅在模板上)和同样的方法。有什么想法吗?
  • 不要使用 self.request。只是请求。
  • 如果我这样做UserSubscription.objects.filter(user=request.user),我会收到错误NameError: name 'request' is not defined。因为这是一个基于类的视图,我需要使用self.request.user。这样我就不会得到描述的错误。话虽如此,我仍然无法获得该用户的订阅。
  • 在模板上,您可以尝试遍历用户订阅,因为它是一个外键,表示多对一关系。见编辑
  • 感谢您的帮助。通过添加 .last() 解决(获取特定用户的最后订阅)。 UserSubscription.objects.filter(user=self.request.user) 正在返回一个查询集,所以也许我确实可以循环以获得相同的结果
【解决方案2】:

我很乐意通过执行 .last() 来解决这个问题,如下所示: UserSubscription.objects.filter(user=self.request.user).last()

结果:

我目前的计划:1 年

开始日期:2021 年 3 月 9 日晚上 7:49

结束日期:2021 年 3 月 9 日晚上 7:49

续订我的订阅

我的账单:

账单 1:50.0 欧元

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-15
    • 2013-12-13
    • 2013-10-03
    • 1970-01-01
    • 2013-03-23
    • 2014-09-14
    • 1970-01-01
    • 2011-12-11
    相关资源
    最近更新 更多