Django: สร้างหมายเลขซีรีส์ที่กำหนดเองเมื่อบันทึกโมเดล

ฉันยังใหม่กับ django

ฉันมีโมเดล Item ซึ่งมีฟิลด์ property_number และฟิลด์ FK location ถึงโมเดล Location property_number มีรูปแบบดังนี้ 0000-00-00-0000-00 ซึ่งก็คือ [ปี] - [บัญชีย่อย] - [บัญชี gl] - [หมายเลขซีรี่ส์] - [รหัสสถานที่] . ภายใต้รูปแบบ series_number ควรสร้างขึ้นจากการบันทึกฐานบนพารามิเตอร์ location_code

ตัวอย่าง:

รหัสสถานที่: 10

Item 1

property number should be: 2021 - 01 - 01 - 0001 - 10

Item 2

property number should be: 2021 - 01 - 01 - 0002 - 10

Item 3

property number should be: 2021 - 01 - 01 - 0003 - 10 ... และอื่นๆ

property number should be: 2021 - 01 - 01 - 1000 - 10

รหัสสถานที่: 50

Item 1

property number should be: 2021 - 01 - 01 - 0001 - 50

Item 2

property number should be: 2021 - 01 - 01 - 0002 - 50 ... และอื่นๆ

property number should be: 2021 - 01 - 01 - 0055 - 50

รหัสสถานที่: 65

Item 1

property number should be: 2021 - 01 - 01 - 0001 - 65 ... และอื่นๆ

property number should be: 2021 - 01 - 01 - 0100 - 65

*ในตัวอย่างนี้ สำหรับ รหัสสถานที่ 10 รายการที่ 1 รายการที่ 2 และรายการที่ 3 มีหมายเลขซีรีส์ 0001, 0002 และ 0003

และสำหรับ รหัสสถานที่ 50 รายการที่ 1 และรายการที่ 2 มีชุดหมายเลข 0001 และ 0002

และอื่นๆ

แต่ละครั้งที่มีการบันทึกรายการใหม่ด้วยรหัสสถานที่ที่แตกต่างกัน number_series จะถูกรีเซ็ตเป็น 0001 และจะดำเนินต่อไปเมื่อมีการบันทึกรายการใหม่ด้วยรหัสสถานที่เดียวกัน

สิ่งที่ฉันมีจนถึงตอนนี้

ฉันสามารถบันทึกรูปแบบได้แล้วโดยการแทนที่ฟังก์ชัน save แต่ฉันไม่รู้ว่าจะสร้างหมายเลขชุดความปรารถนาได้อย่างไร

def save(self, *args, **kwargs):
    self.property_number = '{}-{}-{}-{}'.format(self.date_acquired.year, self.sub_major_group_and_gl_account.sub_major_group_and_gl_account, 'This is where the series_number is place', self.location.location_code)
    super(Item, self).save(*args, **kwargs)

นี่คือสิ่งที่ฉันมีจนถึงตอนนี้เพื่อสร้าง series_number แต่แน่นอนว่านี่ไม่ถูกต้อง ฉันไม่รู้ด้วยว่าจะเปรียบเทียบข้อมูลใหม่ที่จะบันทึกกับข้อมูลที่บันทึกไว้แล้วอย่างไร

def generate_series_number(self):
    # Get all records and filter by location.location_code and should be compare if there is already a data that has the same location_code
    get_item_location = Item.objects.all().filter(self.location.location_code=='This should be the latest data to be save')

    # Count how many data has the same location_code to know what number series to be assigned
    # if result is, there are already 50 records exist with location_code = '01', the new data will have the series number '51' 
    count_current_data = get_item_location.count()
    assign_series_number = count_current_data + 1

    return assign_series_number

# I will use the 'generate_series_number' function in the save function to format my Property_number field in the model.
def save(self, *args, **kwargs):
    self.property_number = '{}-{}-{}-{}'.format(self.date_acquired.year, self.sub_major_group_and_gl_account.sub_major_group_and_gl_account, 'series_number', self.location.location_code)
    super(Item, self).save(*args, **kwargs)

นี่คือโมเดล Item ของฉัน

class Item(models.Model):
    item                    = models.CharField(max_length=100, null=True)
    description             = models.TextField(max_length=200, null=True)
    date_acquired           = models.DateField(null=True)
    old_property_number     = models.CharField(max_length=100, null=True)
    property_number         = models.CharField(max_length=100, null=True, blank=True)
    unit_of_measure         = models.ForeignKey('Uom', related_name='uom_item', null=True, on_delete=models.SET_NULL)
    unit_value              = models.DecimalField(max_digits=12, decimal_places=2, null=True)
    quantity_per_card           = models.CharField(max_length=100, null=True, default='1')
    quantity_per_physical_count = models.CharField(max_length=100, null=True, default='1' )
    # location_code as primary key
    location                    = models.ForeignKey('Location', related_name='location_item', null=True, on_delete=models.SET_NULL)
    condition                   = models.ForeignKey('Condition', related_name='condition_item', null=True, on_delete=models.SET_NULL)
    accountable_person          = models.ForeignKey('Personnel', related_name='personnel_item', null=True, on_delete=models.SET_NULL)
    remarks                     = models.ForeignKey('Remarks', related_name='remarks_item', null=True, on_delete=models.SET_NULL)
    sub_major_group_and_gl_account    = models.ForeignKey('Account', related_name='sub_major_group_and_gl_account_item', null=True, on_delete=models.SET_NULL)

หมายเหตุ: ฉันไม่มี view.py สิ่งที่ฉันทำงานอยู่ในไซต์ผู้ดูแลระบบเท่านั้น

ฉันยังใหม่กับ Django อย่าโกรธฉันเลย :) ขอบคุณล่วงหน้า


person Markmeplease    schedule 19.04.2021    source แหล่งที่มา


คำตอบ (1)


ฉันกำลังตอบคำถามของฉันเอง

ฉันจัดการเพื่อแก้ไขปัญหาด้วยฟังก์ชัน save ด้านล่าง หากใครสามารถปรับปรุงโซลูชันของฉันได้ก็จะได้รับการชื่นชม

หมายเหตุ: สิ่งนี้ใช้ได้กับอินสแตนซ์ที่เพิ่มใหม่ผ่านทางไซต์ผู้ดูแลระบบเท่านั้น และจะไม่ทำงาน หากนำเข้าอินสแตนซ์ผ่าน django-import-export นั่นคงเป็นปัญหาที่เหลืออยู่สำหรับฉันในการกำหนด data_counter ให้กับทุกๆ อินสแตนซ์โดยอัตโนมัติเมื่อใช้ฟังก์ชันนำเข้าในไซต์ผู้ดูแลระบบ

มิฉะนั้นจะดำเนินการมอบหมายด้วยตนเองในไฟล์ Excel XD

def save(self, *args, **kwargs):
    data_counter = Item.objects.filter(location=self.location).aggregate(counter=Count('id'))['counter'] # Count existing instance with matching "location id" of the new instance
    if self.pk is None and self.property_number is None: # if new instance and property number field is blank
        if data_counter is None: # if data_counter is empty/none, no matching instance
            data_counter = 1  # start at 1
        else: # else, if there is matching instance
            data_counter += 1 # add 1 to the data_counter
    elif self.pk is not None and self.property_number is None: # if not new instance and property number field is blank, Update an instance without property number
        if data_counter is None: # if data_counter is empty/none, the existing instance has no matching location id, Update
            data_counter = 1 # Existing instance start at 1
        else: # else, if there is matching instance
            data_counter += 1 # add 1 to the data_counter

    # data_counter will be the series number for every location ID
    self.property_number = '{}-{}-{:04d}-{}'.format(self.date_acquired.year, self.sub_major_group_and_gl_account.sub_major_group_and_gl_account, data_counter, self.location.location_code)
    
    super(Item, self).save(*args, **kwargs)
person Markmeplease    schedule 20.04.2021