Django: Hasilkan nomor seri khusus setelah menyimpan model

Saya baru mengenal Django.

Saya memiliki model Item yang memiliki bidang property_number dan bidang FK location hingga model Location. property_number mempunyai format seperti ini 0000-00-00-0000-00 yaitu [tahun] - [sub akun] - [akun gl] - [nomor seri] - [kode lokasi] . Di bawah format series_number, ini harus dihasilkan setelah menyimpan berdasarkan parameter location_code.

Contoh:

Kode lokasi: 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 ...dan seterusnya,

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

Kode lokasi: 50

Item 1

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

Item 2

property number should be: 2021 - 01 - 01 - 0002 - 50 ...dan seterusnya,

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

Kode lokasi: 65

Item 1

property number should be: 2021 - 01 - 01 - 0001 - 65 ...dan seterusnya,

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

*Dalam contoh ini, untuk kode lokasi 10, item 1, item 2, dan item 3 memiliki nomor seri 0001, 0002, dan 0003

dan untuk kode lokasi 50, item 1 dan item 2 mempunyai rangkaian nomor 0001 dan 0002

Dan seterusnya

Setiap kali Item baru disimpan dengan kode lokasi berbeda, nomor_seri akan direset ke 0001, dan akan dilanjutkan ketika Item baru disimpan dengan kode lokasi yang sama

Apa yang saya miliki sejauh ini

Saya sudah dapat menyimpan format dengan mengganti fungsi save, tetapi saya tidak tahu cara menghasilkan nomor seri yang diinginkan.

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)

Inilah yang saya miliki sejauh ini untuk menghasilkan series_number, tapi tentu saja ini tidak benar. Saya juga tidak tahu bagaimana cara membandingkan data baru yang akan disimpan dan data yang sudah disimpan.

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)

Ini adalah model Item saya

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)

CATATAN: Saya tidak memiliki view.py, yang saya kerjakan hanya di situs admin.

Saya baru mengenal Django, jangan marah kepada saya :) Terima kasih sebelumnya.


person Markmeplease    schedule 19.04.2021    source sumber


Jawaban (1)


Saya menjawab pertanyaan saya sendiri.

Saya berhasil memecahkan masalah saya dengan fungsi save di bawah ini. jika ada yang bisa meningkatkan solusi saya, itu akan dihargai.

Catatan: Ini hanya berlaku pada instance yang baru ditambahkan melalui situs admin dan TIDAK AKAN BEKERJA jika instance diimpor melalui Django-import-export. Jadi, itu akan menjadi masalah yang tersisa bagi saya, untuk secara otomatis menetapkan data_counter untuk setiap contoh ketika menggunakan fungsi impor di situs admin.

Jika tidak, akan mengerjakan tugas secara manual di file 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