Home > database >  Django Auto Increment Field Non Pk
Django Auto Increment Field Non Pk

Time:10-31

How to make the model so that each order that a costumer submit is gonna be auto incremented (ie. order_number) without messing with the order obj primary_key?

Models.py

class Costumer(models.Model):
    costumer_name = models.CharField(max_length=100)
    costumerID = models.CharField(max_length=100)

class Order(models.Model):
    costumer = models.ForeignKey(Costumer, related_name='order', on_delete=models.CASCADE)
    order_name = models.CharField(max_length=100)
    order_number = models.IntegerField(default=0)

JSON Example

[
    {
        "id": 1,
        "order": [
            {
                "id": 1,
                "order_name": "fruit",
                "order_number": 1,
                "costumer": 1
            },
            {
                "id": 2,
                "order_name": "chair",
                "order_number": 2,
                "costumer": 1
            },
            {
                "id": 3,
                "order_name": "pc",
                "order_number": 3,
                "costumer": 1
            }
        ],
        "costumer_name": "john doe",
        "costumerID": "81498"
    },
    {
        "id": 2,
        "order": [
            {
                "id": 4,
                "order_name": "phone",
                "order_number": 1,
                "costumer": 2
            },
            {
                "id": 5,
                "order_name": "car",
                "order_number": 2,
                "costumer": 2
            }
        ],
        "costumer_name": "jane doe",
        "costumerID": "81499"
    }
]

If i need to submit more file such as seriallizers.py etc please let me know. Thank you in advance.

CodePudding user response:

You can use an AutoField. django documentation speak about that here: https://docs.djangoproject.com/en/3.2/ref/models/fields/#autofield

CodePudding user response:

What I think could work is using an IntegerField (pretty much what an AutoField uses under the hood), and increment that on the model's first save (before it's ever put into the database).

example:

from django.db import models

class MyModel(models.Model):

    # This is what you would increment on save
    # Default this to one as a starting point
    display_id = models.IntegerField(default=1)

    # Rest of your model data

    def save(self, *args, **kwargs):
        # This means that the model isn't saved to the database yet
        if self._state.adding:
            # Get the maximum display_id value from the database
            last_id = self.objects.all().aggregate(largest=models.Max('display_id'))['largest']

            # aggregate can return None! Check it first.
            # If it isn't none, just use the last ID specified (which should be the greatest) and add one to it
            if last_id is not None:
                self.display_id = last_id   1

        super(MyModel, self).save(*args, **kwargs)

CodePudding user response:

You could override the save function when an order is created and set the order number at that point based on the maximum of the other customer orders

class Order(models.Model):
    costumer = models.ForeignKey(Costumer, related_name='order', on_delete=models.CASCADE)
    order_name = models.CharField(max_length=100)
    order_number = models.IntegerField(default=0)

    def save(self, *args, **kwargs):
        if not self.pk:
            # get all your customers orders and get the last order number
            last_order = self.customer.order.all().order_by('order_number').last()
            self.order_number = last_order.order_number   1
        
        super(Order, self).save(*args, **kwargs)

  • Related