【问题标题】:Accessing model attributes in Django在 Django 中访问模型属性
【发布时间】:2020-05-05 17:09:27
【问题描述】:

我正在尝试向用户展示他们选择的产品变体。虽然代码正在运行并将变化保存在数据库中,但我无法在我的 html 页面上显示它们。只有: 正在呈现。如果我尝试{{ order_item.variation.all }},它会给出一个空查询集,例如:<QuerySet []>。如果我尝试{{ order_item.variation }},它会说:products.Variation.None。问题是什么?我叫它的方式不对吗?这是我尝试过的:

我的models.py:

class Variation(models.Model):
    item = models.ForeignKey(Item, on_delete=models.CASCADE, null=True, blank=True)
    variation_type = models.CharField(max_length=120, choices=VAR_TYPES, default='Size')
    title = models.CharField(max_length=120, null=True, blank=True)
    price = models.FloatField(null=True, blank=True)
    is_available = models.BooleanField(default=True)

    objects = VariationManager()

class OrderItem(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    item  = models.ForeignKey(Item, on_delete=models.CASCADE)
    variation = models.ManyToManyField(Variation)
    quantity = models.IntegerField(default=1)
    ordered = models.BooleanField(default=False)

class Order(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    ref_code = models.CharField(max_length=20)
    ordered = models.BooleanField(default=False)
    items = models.ManyToManyField(OrderItem)
    variation = models.ManyToManyField(Variation)

我的 order_summary.html:


{% for order_item in object.items.all %}
  <tbody>
    <tr>
      <th scope="row" class="border-0">
        <div class="p-2">
          <img src="{{ order_item.item.image_url }}" alt="" width="70" class="img-fluid rounded shadow-sm">
            <div class="ml-3 d-inline-block align-middle">
              <h5 class="mb-0"> <a href="{{ order_item.item.get_absolute_url }}" class="text-dark d-inline-block align-middle">{{ order_item.item.title }}</a>
              {% if order_item.variation %}
               <ul>
                 <h6>{{ order_item.variation.variation_type }} : {{ order_item.variation.title }}</h6>
               </ul>
             {% endif %}
            </div>
          </div>
       </th>

我的意见.py:

@login_required
def add_to_cart(request, slug):
    item = get_object_or_404(Item, slug=slug)

    order_item, created = OrderItem.objects.get_or_create(
        item=item,
        user= request.user,
        ordered=False,
    )
    order_qs = Order.objects.filter(user=request.user, ordered=False)
    if order_qs.exists():
        order = order_qs[0]
        if order.items.filter(item__slug=item.slug).exists():
            order_item.quantity += 1
            order_item.save()
            messages.success(request, "Product quantity has been updated.")
        else:

            order.items.add(order_item)
            messages.success(request, "Product added to cart.")
            return redirect("order-summary")
    else:
        ordered_date = timezone.now()
        order = Order.objects.create(user=request.user, ordered_date=ordered_date)
        order.items.add(order_item)
        messages.success(request, "Product added to cart.")
        return redirect("order-summary")
    return redirect("order-summary")




class OrderSummaryView(LoginRequiredMixin, View):
    def get(self, *args, **kwargs):
        try:
            order = Order.objects.get(user=self.request.user, ordered=False)
            context = {
                'object': order
            }
            return render(self.request, 'orders/order_summary.html', context)

        except ObjectDoesNotExist:
            messages.warning(self.request, "You do not have an active order")
            return redirect("/")

【问题讨论】:

  • 您应该在模型中进行一些重构,以使您的代码更具可读性,并且很可能会解决您的问题。 ForeignKey 和 ManyToManyField 应使用参数 related_name docs.djangoproject.com/en/3.0/ref/models/fields/… 声明。在您的视图中尝试打印(order.variation)并确认其为空。 Order 模型不应该需要 Variation 外键,因为 OrderItem 已经有了它
  • 用户可以在将产品添加到购物车时选择变体。我已经用 add_to_cart 视图更新了我的问题。是因为它而发生的吗?
  • 是的,他们可以更改 OrderItem 的变体...这没有数据库模型的意义。
  • 重新考虑您的数据库模式和实施。并阅读有关 related_name 的文档,这对于您要实现的目标非常重要
  • 好的朋友,稍后我会发布一个更具体的解决方案,以提供更多帮助

标签: html django django-models


【解决方案1】:

models.py的重构:

class Variation(models.Model):
    item = models.ForeignKey(Item, related_name='item_variations', on_delete=models.CASCADE, null=True, blank=True)
    variation_type = models.CharField(max_length=120, choices=VAR_TYPES, default='Size')
    title = models.CharField(max_length=120, null=True, blank=True)
    price = models.FloatField(null=True, blank=True)
    is_available = models.BooleanField(default=True)

    objects = VariationManager()

class Order(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='orders', on_delete=models.CASCADE)
    ref_code = models.CharField(max_length=20)
    ordered = models.BooleanField(default=False)

class OrderItem(models.Model):
    order = models.ForeignKey(Order, related_name='order_order_items', on_delete=models.CASCADE)
    item = models.ForeignKey(Item, related_name='item_order_items', on_delete=models.CASCADE)
    variation = models.ForeignKey(Variation, related_name='order_item_variations', on_delete=models.CASCADE, null=True, blank=True)
    quantity = models.IntegerField(default=1)

您可以通过以下示例访问用户的订单

first_user = User.objects.all().first()
orders = first_user.orders.all()

您可以通过以下示例访问您订单的商品

first_order = Order.objects.all().first()
order_items = first_order.order_items.all()

您需要重构 html 和 views.py,但它应该非常简单

【讨论】:

  • 但是兄弟,在 Order 模型上添加variation = models.ForeignKey(Variation, related_name='order_item_variations', on_delete=models.CASCADE) 不是更好吗?因为那是我存储所有 order_items 和所有东西的地方
  • 如果您不介意,您能否说明如何在我的 add_to_cart 视图中添加变体部分并在我的 html 中访问它?提前非常感谢!
  • 否,因为变化是相对于商品而非订单的。对于第一个问题
  • 关于第二个问题,您需要在您的 url 和 add_to_cart 方法中添加第二个 slug 并查询数据库,然后将其添加到您正在创建的 order_item 中
  • 但不是每个产品都会有变化
猜你喜欢
  • 1970-01-01
  • 2011-06-06
  • 1970-01-01
  • 2017-05-04
  • 1970-01-01
  • 1970-01-01
  • 2014-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多