1

ビュー関数の GET 部分で、モデルの既存のインスタンスを使用して ModelForm ベースのフォームをインスタンス化するという問題が発生しています。このモデルにはすでにいくつかのフィールドが入力されています。ModelForm は、モデル内の他のフィールドを収集するために使用されます。ModelForm の定義では、既存のフィールドは除外されます。

問題は、POST 処理中に ModelForm の検証が成功した後、ModelForm.save(commit=False) を呼び出していることです...そしてモデルが返されます (これは、 GET 処理、覚えておいてください) 以前に設定されたすべてのフィールドがどういうわけか失われました。フォームによって実際に設定されたフィールドは問題ありません。しかし、それはもはや私のモデルの元のインスタンスではありません。

これは私が期待した動作ではありません。実際、私は以前にこのモデル形式の部分モデルを使用したことがあり、他の場所でも機能します。ここで何が欠けていますか??

うまくいけば、いくつかのコードがこのすべてを明確にするでしょう...

モデルは次のとおりです。

class Order(models.Model):

    STATUS = (
       ('Created', -1),
       ('Pending', 0),
       ('Charged', 1),
       ('Credited', 2),
    )

    SHIPPING_STATUS = (
       ('Cancelled', 0),
       ('Ready for pickup', 1),
       ('Shipped', 2),
       ('OTC', 3),
    )

    orderID = models.IntegerField(max_length=15, null=True, blank=True)
    store = models.ForeignKey(Store)
    paymentInstrument = models.ForeignKey(PaymentInstrument, null=True, blank=True)
    shippingMethod = models.ForeignKey(ShippingMethod, null=True, blank=True)

    last_modified = models.DateTimeField(null=True, blank=True)
    date = models.DateTimeField(auto_now_add=True, null=True, blank=True)

    total = models.FloatField(default=0.0, blank=True)
    shippingCharge = models.FloatField(default=0.0, blank=True)
    tax = models.FloatField(default=0.0, blank=True)

    status = models.CharField(max_length=50, choices=STATUS, default = 'Created')
    shippingStatus = models.CharField(max_length=50, choices=SHIPPING_STATUS, default = '1')

    errstr = models.CharField(max_length=100, null=True, blank=True)

    #  billing info
    billingFirstname = models.CharField(max_length = 50, blank = True)
    billingLastname = models.CharField(max_length = 50, blank = True)
    billingStreet_line1 = models.CharField(max_length = 100, blank = True)
    billingStreet_line2 = models.CharField(max_length = 100, blank = True)
    billingZipcode = models.CharField(max_length = 5, blank = True)
    billingCity = models.CharField(max_length = 100, blank = True)
    billingState = models.CharField(max_length = 100, blank = True)
    billingCountry = models.CharField(max_length = 100, blank = True)

    email = models.EmailField(max_length=100, blank = True)
    phone = models.CharField(max_length=20, default='', null=True, blank=True)

    shipToBillingAddress = models.BooleanField(default=False)

    #  shipping info
    shippingFirstname = models.CharField(max_length = 50, blank = True)
    shippingLastname = models.CharField(max_length = 50, blank = True)
    shippingStreet_line1 = models.CharField(max_length = 100, blank = True)
    shippingStreet_line2 = models.CharField(max_length = 100, blank = True)
    shippingZipcode = models.CharField(max_length = 5, blank = True)
    shippingCity = models.CharField(max_length = 100, blank = True)
    shippingState = models.CharField(max_length = 100, blank = True)
    shippingCountry = models.CharField(max_length = 100, blank = True)

ModelForm の定義は次のとおりです。

class OrderForm(ModelForm):

   class Meta:
      model = Order
      exclude = ('orderID',
                 'store', 
                 'shippingMethod', 
                 'shippingStatus', 
                 'paymentInstrument',
                 'last_modified',
                 'date',
                 'total',
                 'payportCharge',
                 'errstr',
                 'status', )
      widgets = {
          'billingCountry': Select(choices = COUNTRIES, attrs = {'size': "1"}),
          'shippingCountry': Select(choices = COUNTRIES, attrs = {'size': "1"}),
          'billingState': Select(choices = STATES, attrs = {'size': "1"}),
          'shippingState': Select(choices = STATES, attrs = {'size': "1"}),
                 }

そして、ビュー関数は次のとおりです。

def checkout(request):

    theDict = {}

    store = request.session['currentStore']
    cart = request.session.get('cart', False)
    order = request.session['currentOrder'] # some fields already set
    if not cart:   # ...then we don't belong on this page.
        return HttpResponseRedirect('/%s' % store.urlPrefix)

    if request.method == 'GET':

        form = OrderForm(instance=order, prefix='orderForm')

    else:    # request.method == 'POST':
        logging.info("Processing POST data...")

        form = OrderForm(request.POST, prefix='orderForm')

        if form.is_valid():
            ### AT THIS POINT, ORDER FIELDS ARE STILL GOOD (I.E. FILLED IN)
            order = form.save(commit=False)
            ### AFTER THE SAVE, WE'VE LOST PRE-EXISTING FIELDS; ONLY ONES SET ARE
            ### THOSE FILLED IN BY THE FORM.

            chargeDict = store.calculateCharge(order, cart)

            request.session['currentOrder'] = order

            return HttpResponseRedirect('/%s/payment' % store.urlPrefix)

        else:  
            logging.info("Form is NOT valid; errors:")
            logging.info(form._errors)

            messages.error(request, form._errors)

    theDict['form'] = form
    theDict['productMenu'] = buildCategoryList(store)

    t = loader.get_template('checkout.html')
    c = RequestContext(request, theDict)

    return HttpResponse(t.render(c))

あらゆる/すべての助けに感謝します...

4

1 に答える 1