Home > Software engineering >  Django generate custom cheque number
Django generate custom cheque number

Time:10-07

I'm new in django, I want to create custom Cart number that starts with #. When a new record comes into database. #1-1000, #1-1001, #1-9999, .... #2-1000, ...#2-9999 etc.

This is my model
class Cart(models.Model):
    # id = models.CharField(primary_key=True, editable=False, max_length=10)
    user = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name="cart")
    create_date = models.DateField(auto_now_add=True)
    cart_number = models.CharField(max_length=500, default=increment_cart_number, null=True, blank=True)
    total_summa = models.FloatField()
    time = models.TimeField(auto_now_add=True)

The cart_number will be always in range 1000- 9999 so how can I do that with increment_cart_number function?

CodePudding user response:

def increment_cart_number():
    last_cart_number = Cart.objects.last()
    if last_cart_number.exists():
       last_num = last_cart_number.cart_number.replace('#','').split('-')
       if int(last_num[1]) >= 9999:
          first_number = int(last_num[0])   1
          secound_number = 1000
          result = '#'  str(first_number)  '-'  str(secound_number)
          return result
       elif int(last_num[1]) < 9999:
           secound_number = int(last_num[1])   1
           result = '#'  last_num[0]  '-'  str(secound_number)
           return result
     else:
         return '#1-1000'

But I suggest to you for more cleaner way and best practice to do it in another way:

Make this field as AutoField and make defalut value 1000 to start from it.

cart_number = models.AutoField(auto_created = True, default=1000)

After that when you want to print this value add '#' to it from frontend that will be better and faster and easier.

CodePudding user response:

Create a function, that finds a next cart_number:

class Cart(models.Model):
    ...
    def get_next_cart_number(self):
        cart_query = Cart.objects.filter(cart_number__isnull=False)
        if not cart_query:
            return '#1-1000'
        number = list(map(int, cart_query.last().cart_number.replace("#", "").split("-")))
        if number[1] == 9999:
            number[0]  = 1
            number[1] = 1000
        return f"#{number[0]}-{number[1]}"

Then add signals, so it will be set just at the creation. Create file signals.py inside the app:

from my_app.models import Cart
from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=Cart)
def create_user_profile(sender, instance, created, **kwargs):
    if created and not instance.cart_number:
        instance.cart_number = instance.get_next_cart_number()
        instance.save()

And import signals file inside your apps.py in the same app:

class MyAppConfig(AppConfig):
    ...
    def ready(self):
        from . import signals

In this way every time you will create Cart object, just after his first save (created variable tells it that) it will find and set a new cart number. Remember, that it's important that you keep blank=True and null=True attributes.

  • Related