Rahul Verma
Rahul Verma

Reputation: 563

Django ModelManager not saving the model instance correctly

I am working on an ecommerce project but my OrderManager() class does not saving the instance(i think) When i am clicking on BOOK button i am getting this error which is defined in my view

order_amount = order_obj.total * 100
AttributeError: 'NoneType' object has no attribute 'total'

But when i refresh the page error goes way and order_obj.total * 100 is calculated, But my question is why i need to refresh the page again and again when i create a new order.

Here is my models.py

class OrderQuerySet(models.query.QuerySet):
    def not_created(self):
        return self.exclude(status='created')


class OrderManager(models.Manager):

    def get_queryset(self):
        return OrderQuerySet(self.model, using=self.db)

    def create_or_get_order(self, product):
        created = None
        obj = None
        qs = self.get_queryset().filter(product=product, active=True, status='created')
        if qs.count() == 1:
            obj = qs.first()
        else:
            self.model.objects.create(product=product)
            created = True
        return obj, created


class Order(models.Model):
    order_id = models.CharField(max_length=120, blank=True)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    total = models.PositiveIntegerField()
    active = models.BooleanField(default=True)

    objects = OrderManager()

    class Meta:
        ordering = ['-ordered_on', '-updated']

    def __str__(self):
        return self.order_id

    def check_done(self):      # check everything is correct before final checkout
        order_id = self.order_id
        total = self.total
        if order_id and total > 0:
            return True
        return False

    def mark_paid(self):
        if self.check_done():
            self.status = 'paid'
            self.save()
        return self.status


def pre_save_create_order_id(sender, instance, *args, **kwargs):
    if not instance.order_id:
        instance.order_id = unique_order_id_generator(instance)


pre_save.connect(pre_save_create_order_id, sender=Order)


def pre_save_order_total(sender, instance, *args, **kwargs):
    """calculate the product total while clicking on Book Button
    (Still booking is not done you just clicked on Book button)"""

    instance.total = instance.product.price


pre_save.connect(pre_save_order_total, sender=Order)

Views.py

def checkout_home_view(request, *args, **kwargs):
    order_obj = None
    order_amount = None
    order_currency = None
    order_id = None

    slug = kwargs['slug']
    product = Product.objects.get(slug=slug)

    if product is not None:

       # ****************** Here is problem ******************************
        order_obj, order_create = Order.objects.create_or_get_order(product)
        ''' HERE I AM GETTING order_obj as None BUT WHEN I REFRESH ERROR GOES WAY '''
        print('order_obj', order_obj)  # printing None initally   
        order_amount = order_obj.total * 100


        order_currency = 'INR'
        order_id = order_obj.order_id
    if request.method == 'POST':
        'check that booking is done'
        is_prepared = order_obj.check_done()  # check_done() defined in Order model
        if is_prepared:
            client = razorpay.Client(auth=("xxx", "xxx"))
            payment = client.order.create(dict(amount=order_amount, currency=order_currency))

            if payment:
                order_obj.mark_paid()  # mark_paid() defined in Order model
                order_obj.save()

Upvotes: 0

Views: 43

Answers (1)

Himanshu Patel
Himanshu Patel

Reputation: 640

class OrderManager(models.Manager):
   ...

    def create_or_get_order(self, product):
        created = None
        obj = None
        qs = self.get_queryset().filter(product=product, active=True, status='created')
        if qs.count() == 1:
            obj = qs.first()
        else:
            # -------------- catch the returned obj and return --------------
            obj = self.model.objects.create(product=product)
            created = True
        return obj, created

Upvotes: 1

Related Questions