【问题标题】:Django to clear data causing save() prohibited to prevent data loss due to unsaved related objectDjango清除数据导致save()被禁止以防止由于未保存的相关对象导致数据丢失
【发布时间】:2018-03-27 08:39:34
【问题描述】:

我需要知道如何清除导致以下错误的未保存的相关数据:

save() 禁止保存,以防止由于未保存的相关对象“订单”而导致数据丢失。

我的代码按预期工作,但我未能完成订单。从那时起,任何保存新订单的尝试都会导致上述错误。我知道原因是对django.db.models.base.py 的更改,但必须有某种方法可以通过日志或其他方式清除它... 我已经尝试重新创建数据库以及 sqlflush 命令,但都没有工作。

观看次数

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import weasyprint
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.admin.views.decorators import staff_member_required
from django.core.urlresolvers import reverse
from django.conf import settings
from django.http import HttpResponse
from django.template.loader import render_to_string
from .models import OrderItem, Order
from .forms import OrderCreateForm
from cart.cart import Cart
from .tasks import order_created
# Create your views here.
@staff_member_required
def admin_order_detail(request, order_id):
    order = get_object_or_404(Order, id=order_id)
    return render(request, 'admin/orders/order/detail.html', {'order': order})

@staff_member_required
def admin_order_pdf(request, order_id):
    order = get_object_or_404(Order, id=order_id)
    html = render_to_string('orders/order/pdf.html', {'order': order})
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'filename="order_{}.pdf"'.format(order.id)
    weasyprint.HTML(string=html).write_pdf(response, stylesheets=[weasyprint.CSS(settings.STATIC_ROOT + 'css/pdf.css')])

    return response


def order_create(request):
    cart = Cart(request)
    if request.method == 'POST':
        form = OrderCreateForm(request.POST)
        if form.is_valid():
            order = form.save(commit=False)
            if cart.coupon:
                order.coupon = cart.coupon
                order.discount = cart.coupon.discount
                order.save()
            for item in cart:
                OrderItem.objects.create(order=order, product=item['product'], price=item['price'], quantity=item['quantity'])
            #emptying the cart
            cart.clear()
            #launch celery async task
            order_created.delay(order.id)
            request.session['order_id'] = order.id #set order.id session
            return redirect(reverse('payment:process'))
    else:
        form = OrderCreateForm()
    return render(request, 'orders/order/create.html', {'cart': cart, 'form':form})

模型

class Order(models.Model):
    first_name = models.CharField(_('first_name'),max_length=50)
    last_name = models.CharField(_('last_name'),max_length=50)
    email = models.EmailField(_('email'),)
    address = models.CharField(_('address'),max_length=250)
    postal_code = models.CharField(_('postal_code'),max_length=250)
    city = models.CharField(_('city'),max_length=100)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    paid = models.BooleanField(default=False)
    coupon = models.ForeignKey(Coupon, related_name='orders', null=True, blank=True)
    discount = models.IntegerField(default=0, validators=[MinValueValidator(0), MaxValueValidator(100)])

    class Meta:
        ordering = ('-created',)

    def __unicode__(self):
        return 'Order {}'.format(self.id)

    def get_total_cost(self):
        total_cost  = sum(item.get_cost() for item in self.items.all())
        return total_cost - total_cost *(self.discount)

class OrderItem(models.Model):
    order = models.ForeignKey(Order, related_name='items')
    product = models.ForeignKey(Product, related_name='order_items')
    price = models.DecimalField(max_digits=10, decimal_places=2)
    quantity = models.PositiveIntegerField(default=1)

    def __unicode__(self):
        return '{}'.format(self.id)

    def get_cost(self):
        return self.price * self.quantity

表格

from django import forms
from .models import Order


class OrderCreateForm(forms.ModelForm):
    class Meta:
        model = Order
        fields = ['first_name', 'last_name', 'email', 'address', 'postal_code', 'city']

【问题讨论】:

  • 为什么你认为这是模型造成的?在我看来,错误出在您的 view 方法之一中,您可以发布代码吗?我认为this 问题会让您更深入地了解您的错误
  • 我已经通读过了。这就是为什么我认为这是因为模型

标签: django python-2.7


【解决方案1】:

如果您检查您的模型,那么您可以看到order 表中的coupon 字段是一个外键,即相关对象。

因为您没有保存coupon 对象,所以它没有pk 并且无法添加到order。先保存coupon对象,然后添加到订单中。

比如:

coupon = cart.coupon # not sure if this in between step is needed
coupon.save()
order.coupon = coupon
order.save()

【讨论】:

  • ok... 1:失败的操作没有应用优惠券,因为这是在 if 语句中,我不明白你为什么认为优惠券是问题
  • 您是说添加订单失败,我在您的整个代码中只能看到一个order.save(),这是它添加优惠券的地方。这是一个问题,因为您在将优惠券对象添加到订单之前没有save(),这会引发您面临的错误。@PaddyPopeye
  • 2:之前的代码可以正常工作。导致错误的唯一原因是未完成订单流程。我之前看到过这个错误,订单未完成,当我退回到订单并完成时,没有问题。这一次,由于浏览器已关闭,因此不可能这样做,并且自从提交新订单时出现错误以来。在此之前的所有订单,无论是否应用优惠券,都能完美运行。问题的原因是订单中断和未完成,在我看来
  • 根据您的建议输入代码...如果 cart.coupon: coupon = cart.coupon coupon.save() order.discount = coupon.discount order.save(
  • 那我唯一能想到的就是清空你的浏览器缓存
【解决方案2】:

已解决

只需在代码中稍早保存订单对象,因此在 orders.views.py 文件中,在 create_order() 方法中,添加更早的 order.save() 调用 ...

这个

if form.is_valid():
    order = form.save(commit=False)

变成

if form.is_valid():
      order = form.save(commit=False)
      order.save()
    if cart.coupon:
        ............
        ..............

一切正常!

@Snackoverflow 感谢您的帮助 :-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多