如何使用显示多个对象项的视图并在从 Django 数据库中删除其中一项后显示 html?

Posted

技术标签:

【中文标题】如何使用显示多个对象项的视图并在从 Django 数据库中删除其中一项后显示 html?【英文标题】:How can I display html using a view that displays multiple object items and after one of those items has been deleted from the Django database? 【发布时间】:2021-08-11 11:01:33 【问题描述】:

我有以下型号:

CATEGORY_CHOICES = (
    ('Hotel', 'Hotel'),
    ('Restaurant', 'Restaurant'),
    ('Attraction', 'Attraction'),
    ('Activity', 'Activity')
)

LABEL_CHOICES = (
    ('P', 'primary'),
    ('S', 'secondary'),
    ('D', 'danger')
)

class Item(models.Model):
    id = models.AutoField(primary_key=True)  
    name = models.CharField(max_length=64)
    address = models.CharField(max_length=64)
    postcode = models.CharField(max_length=7)
    category = models.CharField(choices=CATEGORY_CHOICES, max_length=20)
    label = models.CharField(choices=LABEL_CHOICES, max_length=1)
    slug = models.SlugField()
    image = models.ImageField(blank=True, null=True, upload_to="images/")    
    description = models.TextField()

    def __str__(self):
        return f"self.id: self.name"

    def get_absolute_url(self):
        return reverse("product", kwargs=
            'slug': self.slug
        )
    
    def get_add_to_cart_url(self):
        return reverse("add-to-cart", kwargs=
            'slug': self.slug
        )

    def get_remove_from_cart_url(self):
        return reverse("remove-from-cart", kwargs=
            'slug': self.slug
        )

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

    def __str__(self):
        return f"self.quantity of self.item.name"


class Order1(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    step = models.CharField(max_length=1, default=0)
    items = models.ManyToManyField(OrderItem)
    start_date = models.DateTimeField(auto_now_add=True)
    ordered_date = models.DateTimeField()
    ordered = models.BooleanField(default=False)
    step_duration = models.FloatField(default=0)   

    def __str__(self):
        return self.user.username
    
    def get_total_duration(self):
        Pass
    
    def get_total_price(self):
        return F"£self.step_duration * 20"


class Order2(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    step = models.CharField(max_length=1, default=0)
    items = models.ManyToManyField(OrderItem)
    start_date = models.DateTimeField(auto_now_add=True)
    ordered_date = models.DateTimeField()
    ordered = models.BooleanField(default=False)
    step_duration = models.FloatField(default=0)   

    def __str__(self):
        return self.user.username
    
    def get_total_duration(self):
        Pass
    
    def get_total_price(self):
        return F"£self.step_duration * 20"

我有以下看法:

@login_required(login_url='login')
def OrderSummaryView(request):
        try:            
            order1 = Order1.objects.get(user=request.user, ordered=False)
            order2 = Order2.objects.get(user=request.user, ordered=False)
            context = 'object1': order1, 'object2': order2
            
            
            return render(request, "order_summary.html", context)
            
            
        except ObjectDoesNotExist:
            messages.error(request, "You do not have an active order")
            return redirect("/")

@login_required
def add_to_cart1(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 = Order1.objects.filter(user=request.user, ordered=False)
    if order_qs.exists():
        order = order_qs[0]
        # check if order item is in the order
        if order.items.filter(item__slug=item.slug).exists():
            order_item.quantity += 1            
            order_item.save()
            messages.info(request, "This item quantity was updated.")
        else:            
            order.items.add(order_item)
            messages.info(request, "This item was added to your cart.")
            return redirect("product", slug=slug)
    else:
        ordered_date = timezone.now()
        order = Order1.objects.create(
            user=request.user, ordered_date=ordered_date, step=1)
        order.items.add(order_item)
        messages.info(request, "This item was added to your cart.")
    return redirect("product", slug=slug)

@login_required
def add_to_cart2(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 = Order2.objects.filter(user=request.user, ordered=False)
    if order_qs.exists():
        order = order_qs[0]
        # check if order item is in the order
        if order.items.filter(item__slug=item.slug).exists():
            order_item.quantity += 1            
            order_item.save()
            messages.info(request, "This item quantity was updated.")
        else:            
            order.items.add(order_item)
            messages.info(request, "This item was added to your cart.")
            return redirect("product", slug=slug)
    else:
        ordered_date = timezone.now()
        order = Order2.objects.create(
            user=request.user, ordered_date=ordered_date)
        order.items.add(order_item)
        messages.info(request, "This item was added to your cart.")
    return redirect("product", slug=slug)


@login_required
def remove_from_cart(request, slug):
    item = get_object_or_404(Item, slug=slug)
    order_qs = Order1.objects.filter(
        user=request.user, 
        ordered=False
        )

    if order_qs.exists():
        order = order_qs[0]
        # check if order item is in the order
        if order.items.filter(item__slug=item.slug).exists():
            order_item = OrderItem.objects.filter(
                item=item,
                user=request.user,
                ordered=False
            )[0]
            # order.items.remove(order_item)                           
            #  order.delete()
            order_item.delete()
            order_qs.delete()

            messages.info(request, "This item was removed from your cart.")
            return redirect("product", slug=slug)
            
        else:
            messages.info(request, "This item was not in your your cart.")
            return redirect("product", slug=slug)
            
    else:        
        messages.info(request, "You do not have an active order.")
        return redirect("product", slug=slug)
        

@login_required
def remove_from_cart2(request, slug):
    item = get_object_or_404(Item, slug=slug)
    order_qs = Order2.objects.filter(
        user=request.user, 
        ordered=False
        )

    if order_qs.exists():
        order = order_qs[0]
        # check if order item is in the order
        if order.items.filter(item__slug=item.slug).exists():
            order_item = OrderItem.objects.filter(
                item=item,
                user=request.user,
                ordered=False
            )[0]
            # order.items.remove(order_item)         
            # order.delete()
            order_item.delete()
            order_qs.delete()
            messages.info(request, "This item was removed from your cart.")
            return redirect("product", slug=slug)
        else:
            messages.info(request, "This item was not in your your cart.")
            return redirect("product", slug=slug)
    else:        
        messages.info(request, "You do not have an active order.")
        return redirect("product", slug=slug)

我有以下 order_summary.html:

% extends "layout.html" %

% block body %
<!--Main layout-->
<main class="mt-5 pt-4">
    <div style="max-width: 70%; position: relative; margin: auto;">
        <!-- <div class="table-responsive text-nowrap"> -->
            <h2>Booking Summary</h2>
            <table class="tabled">
                <thead>
                    <tr>
                        <th scope="col">#</th>
                        <th scope="col">Name</th> 
                        <th scope="col">Address</th>
                        <th scope="col">Category</th>                                             
                    </tr>
                </thead>
                <tbody>
                    % for order_item in object1.items.all %
                    
                    <tr>
                        <!-- <th scope="row"> forloop.counter </th> -->
                        <th scope="row">1</th>
                        <td> order_item.item.name </td>
                        <td> order_item.item.address </td>
                        <td> order_item.item.category </td>
                        <td><a class='btn btn-warning btn-md my-0 p float-right' href="% url 'item-list' %">Edit</a></td>
                        <td><a href="% url 'remove-from-cart' order_item.item.slug %" class="btn btn-danger btn-md my-0 p" >Remove from cart
                        </a></td>
                                             
                    </tr>
                    % empty %
                    <tr>
                        <td colspan="5">Your cart is empty</td>                        
                    </tr>
                    <tr>
                        <td colspan="5">
                            <a class='btn btn-primary float-right' href="% url 'index' %">Continue shopping</a>
                        </td>
                    </tr>
                    % endfor %
                </tbody>
            </table>
            <br>

            <table class="tabled">
                <thead>
                    <tr>
                        <th scope="col"></th>
                        <th scope="col"></th> 
                        <th scope="col"></th>
                        <th scope="col"></th>
                    </tr>
                </thead>
                <tbody>
                    % for order_item in object2.items.all %
                    
                    <tr>
                        <th scope="row">2</th>
                        <td> order_item.item.name </td>
                        <td> order_item.item.address </td>
                        <td> order_item.item.category </td>
                        <td><a class='btn btn-warning btn-md my-0 p float-right' href="% url 'item-list2' %">Edit</a></td>
                        <td><a href="% url 'remove-from-cart2' order_item.item.slug %" class="btn btn-danger btn-md my-0 p" >Remove from cart
                        </a></td>
                                             
                    </tr>
                    % empty %
                    <tr>
                        <td colspan="5">Your cart is empty</td>                        
                    </tr>
                    <tr>
                        <td colspan="5">
                            <a class='btn btn-primary float-right' href="% url 'index' %">Continue shopping</a>
                        </td>
                    </tr>
                    % endfor %
                </tbody>
            </table>        



                    % if object.get_total %
                    <tr>
                        <td colspan="4"><b>Vehicle Size</b></td>
                        <td><b></b></td>
                    </tr>
                    <tr>
                        <td colspan="4"><b>Duration</b></td>
                        <td><b></b></td>
                    </tr>
                    <tr>
                        <td colspan="4"><b>Total Price</b></td>
                        <td><b></b></td>
                    </tr>
                    <tr>
                        <td colspan="5">
                            <a class='btn btn-warning float-right ml-2' href="% url 'checkout' %">Proceed to checkout</a>
                            <a class='btn btn-primary float-right' href="% url 'index' %">Continue shopping</a>                            
                        </td>
                    </tr>
                    % endif %
                </tbody>
            </table>        
        <!-- </div> -->
    </div>
    
    
    
</main>
<!--Main layout-->  
    
% endblock %

在从 Order1 或 Order2 中删除商品并单击显示订单的购物车后,应用程序默认返回到登录 html(应为 order_summary.html)。我希望能够显示显示这两个项目的订单摘要,删除其中一个项目,然后让用户定向到订单摘要(购物车),但只能看到剩余的项目。我认为问题在视图中。谁能帮忙?还有其他视图可以添加和删除 Order1 和 Order2 中的项目。 % if object.get_total % 的 html 底部未完成。

【问题讨论】:

我没有看到您包含删除项目视图。你能包括那个吗?此外,如果这是一个人们将使用的实时站点并且它涉及金钱,我强烈建议您花时间创建测试。这本书的教学很棒:obeythetestinggoat.com/pages/book.html#toc 感谢您的建议。我已经包含了从购物车中添加或删除项目的视图。我希望能够创建以特定顺序创建的项目订单,并允许用户能够从订单中删除/编辑项目。如果在用户完成订单之前将其删除,我将要求更换这些物品。我不确定是否应该为订单提供一个模型或为订单中的每个步骤提供单独的模型。我决定选择单独的模型,因为我认为这些项目在编辑或删除它们时会更容易参考。 我没有所有的细节。从我所看到的情况来看,我会将其设为一个订单类,并带有一个额外的字段,如type 来指定顶部和底部。你有很多重复的代码,很容易隐藏错误。 【参考方案1】:

问题似乎是您在删除项目后重定向到”products” 页面。不包含 urls.py 文件,否则我可以验证重定向名称 ”order_summary” 是否正确。

您在删除视图中看到的每个地方

return redirect("product", slug=slug)

应该是这个。

return redirect("order_summary")

这样它会在完成后将您发送到订单摘要。

【讨论】:

我有重定向到产品页面,该页面显示已删除的项目。当我选择一个按钮返回购物车以查看订单摘要时,order_summary.html 不显示但默认为landing.html。我可以在删除任何内容之前看到订单摘要中显示的项目,所以我不确定为什么删除后没有呈现 order_summary.html。

以上是关于如何使用显示多个对象项的视图并在从 Django 数据库中删除其中一项后显示 html?的主要内容,如果未能解决你的问题,请参考以下文章

Django如何循环对象并在模板中显示变量

禁用添加对象的选项,该对象已经在从 NSUserDefaults 加载的数组中

如何克隆 Django 模型实例对象并在 Django 表单上显示?

来自 django 视图的 2 条消息 [关闭]

如何在 Django 视图中显示 PIL 图像对象?

如何在 django 的单个视图中显示多个 ForeignKey 过滤项目?