我正在使用Django 2.2,并试图创建一个从另一个模型获取信息的模型。我知道ForeignKey,但是这并没有添加我可以从模板中调用的所有对象属性,例如标题,价格等。
我正在销售产品。该产品可以用于女性,也可以用于男性。 我在模型中有一个类别选择,可让我选择是男性还是女性。如果类别选择为“女士”,那么我希望该产品可以作为对象添加到“女士”模型中。这是我的模特:产品,女士专用。
TOY_CATEGORY_CHOICES = (
('FW', 'For Women'),
('FM', 'For Men')
)
class Product(models.Model):
slug = models.SlugField(max_length=40)
image = models.ImageField(upload_to='media')
title = models.CharField(max_length=150)
description = models.TextField()
price = models.DecimalField(max_digits=5, decimal_places=2)
stock_quantity = models.PositiveIntegerField()
in_stock = models.BooleanField(default=True)
category = models.CharField(choices=TOY_CATEGORY_CHOICES, max_length=2, default='FW')
brand = models.CharField(choices=TOY_BRAND_CHOICES, max_length=2, default='NB')
on_sale = models.BooleanField(default=False)
def __str__(self):
return self.title
class ForWomen(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
这是我的观点:
def WomenOnlyView(request):
obj = ForWomen.objects.all()
context = {
'object':obj
}
return render (request, 'products/forwomen.html')
这是我的URL文件:
urlpatterns = [
path('products/for-women/', WomenOnlyView, name='for-women'),
]
这是我的Django模板:
{% block body %}
{% for product in objects %}
<section id="catalogue">
<div class="row">
<div class="col-md-3">
<div class="card">
<img src="" alt="Women" class="card-img-top">
<div class="card-body">
<h1>
{{ objects.title }}
</h1>
<p>
{{ objects.description }}
</p>
<small>
{{ objects.price }}
</small>
</div>
</div>
</div>
</div>
</section>
{% endfor %}
{% endblock %}
我希望能够在网站的管理部分中添加产品,然后仅当类别=='FW'作为对象可以从ForWomen内部访问时才可以使用该产品,并且标题,图像和价格都可以访问。
我希望这有道理,并且有人能够提供帮助。
谢谢!
答案 0 :(得分:4)
您的设计完全是错误的。您不需要那些“女性”或任何型号,您要做的就是过滤产品类别,即obj = Product.objects.filter(category="FW")
。
您的视图也是错误的-构建查询集,使用此查询集构建上下文,但没有将上下文传递给模板。您想要类似的东西:
def WomenOnlyView(request):
obj = Product.objects.filter(category="FW")
context = {
'object':obj
}
return render(
request, 'products/forwomen.html', context=context
)
请注意,您可能希望将常见的过滤操作分解为ModelManager
或QuerySet
方法(请参阅Ruddra关于如何使用自定义方法创建自定义管理器的答案,以及cf. how to write a custom queryset。
现在您的模板代码也完全错误。
首先,在您的上下文中,您将查询集传递为“对象”(单数),但是在模板中,您尝试对名为“对象”(复数)的上下文变量进行迭代。您必须修复上下文或模板。在您的情况下,由于您传递的是QuerySet
(IOW是一种集合),因此您需要在上下文中固定命名(变量名上的复数表示事物的“集合”), IOW,您的观点应该是:
def WomenOnlyView(request):
obj = Product.objects.filter(category="FW")
context = {
'objects':obj
}
return render(
request, 'products/forwomen.html', context=context
)
然后在您的模板中,您正在正确地遍历此查询集:
{% for product in objects %}
# code here
{% endfor %}
但是在循环体内,您试图自己访问查询集(“对象”)上的产品属性:
{% for product in objects %}
<h1>
{{ objects.title }}
</h1>
{% endfor %}
您要在此处使用迭代变量product
:
{% for product in objects %}
<h1>
{{ product.title }}
</h1>
{% endfor %}
最后一点:我(非常强烈地)建议您花一些时间阅读正式文档(并首先阅读完整的官方教程)。详细了解关系模型,关系(SQL)数据库和适当的关系设计。
答案 1 :(得分:1)
可能更好的方法是使用Proxy Model
。然后覆盖Manager
,以获取专为女性设计的Products
。例如:
class ForWomenManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(category='FW')
class ForWomen(Product):
objects = ForWomenManager()
class Meta:
proxy = True
它将提供与Product
模型的隔离,您也可以使用ForWomen.objects.all()
访问女士产品。