显示来自ManyToMany字段的所有数据

时间:2018-10-30 16:03:58

标签: django

我正尝试从多哥关系中获取所有数据,这是我的模型

class Product(models.Model):

    name = models.CharField(max_length=100)
    image = models.FileField(upload_to='products/', null=True)
    price = models.FloatField(default=0)
    stock = models.CharField(max_length=15)
    categories = models.ManyToManyField(Categories)
    def __str__(self):
        return self.name

class Categories(models.Model):
   name =  models.CharField(max_length=100)
    def __str__(self):
        return self.name

要从产品中获取数据,请尝试以下操作:

class Products(ListView):

    model = Product
    template_name = "products.html"

在模板上的返回类似于:

_______________________________
# | name  | price | Categories |
________________________________
1 | Pepsi | 1.25  |            |
2 | Choco.| 2.50  |            |

为了生成此表,我使用以下循环:

{% for product in object_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ product.name }}</td>
<td>{{ product.price }}</td>
<td>{{ product.categories }}</td>
{% endfor %}

在这种情况下,请返回空白产品上选择的类别。.请提出任何建议..谢谢!!

1 个答案:

答案 0 :(得分:1)

请注意,categories的{​​{1}}属性是多对多关系,因此它解析为另一个具有多个对象的查询。这是另一个查询集,仅在您的Product行中,因此您需要明确告诉模板如何打印。

这是一个示例解决方案:

object_list

或者您可以使用django联接模板标签(https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#join):

{% for product in object_list %}
    <tr>
    <td>{{ forloop.counter }}</td>
    <td>{{ product.name }}</td>
    <td>{{ product.price }}</td>
    <td>
        {% for category in product.categories.all %}
            {{ category }}
        {% endfor %}
    </td>
{% endfor %}

自启动Django以来,还有一些快速的注释可以为您提供帮助:

  • {% for product in object_list %} <tr> <td>{{ forloop.counter }}</td> <td>{{ product.name }}</td> <td>{{ product.price }}</td> <td>{{ product.categories.all|join:", " }}</td> {% endfor %} 在您的模型中不是一个很好的名字。我建议将其命名为class Categories,因为每个class Category实例将与一个类别相关。
  • Category是视图的不好的名字。我建议将其命名为class Products,这样您就会知道它是您产品的ListView。并为所有视图保留类似的命名方案。
  • 使用class ProductListView节省价格(货币价值)始终是有问题的。当您尝试对该列进行汇总时(即加或取平均值),您会得到奇怪的值。这是因为浮点数是如何工作的(即某些值不能用浮点数精确表示,但是您会得到非常接近的近似值,而不是像1.3那样具有1.2999999999999的浮点数)。请使用FloatField来正确保存货币值。
  • 您可以将DecimalField属性传递给context_object_name,以便可以使用它代替ListView。因此,如果您这样定义object_list
    class ProductListView(ListView):
        model = Product
        template_name = "products.html"        
        context_object_name = 'products'

您将可以在模板中执行ProductListView

  

我们可以通过在视图中添加template_name属性来明确告知视图要使用哪个模板,但是如果没有明确的模板,Django会从对象名称中推断出一个模板。在这种情况下,推断的模板将是“ books / publisher_list.html” –“ books”部分来自定义模型的应用程序的名称,而“ publisher”位只是该模型名称的小写版本。

仅当您打算为类添加第二个列表视图以明确表明这是故意的时,才使用template_name