首页 > 解决方案 > 在 django 中显示行号

问题描述

情况如下:我有一个 Transaction 模型,它应该注册一些金融交易,我想知道交易的实际数量。最初我使用主键,但我希望有一个单独的字段来跟踪这一点,因为如果删除了一行,我希望减少行号。例如,如果我有 10 行,我添加数字 11,然后删除它,当我添加新行时,它将是数字 11(而不是主键的 12)。我意识到这个解决方案只有在最后一行被删除时才可以。

我所做的是创建一个模型 ( Meta_Stuff) 来存储实际的交易编号。然后,我创建了在删除或创建事务时递减和递增事务编号的方法。

这是代码:

class Meta_Stuff(models.Model):
    # only one instance
    transac_number = models.IntegerField(default=1)

    def __str__(self):
        return self.transac_number

    @classmethod
    def get_lastnumber(cls, default=1):
        return cls.objects.get(pk=1).transac_number
        # number = get_object_or_404(cls, pk=default)
        # return number.transac_number

    @classmethod
    def increment_lastnumber(cls):
        new = cls.objects.get(pk=1)
        new.transac_number += 1
        new.save()

    @classmethod
    def decrement_lastnumber(cls):
        new = cls.objects.get(pk=1)
        if new.transac_number >1:
            new.transac_number -= 1
            new.save()


class Transaction(models.Model):
    numero = models.IntegerField(default=Meta_Stuff.get_lastnumber)
    # numero = models.IntegerField(default=Meta_Stuff.objects.first().transac_number)
    nom = models.CharField(max_length=140)
    somme = models.DecimalField(max_digits=11, decimal_places=2)
    compte = models.ForeignKey(Compte, on_delete=models.CASCADE)
    budget = models.ForeignKey(Budget, on_delete=models.CASCADE, blank=True, null=True)
    date = models.DateField()
    date_traitement = models.DateField(default=datetime.now)
    description = models.TextField()

    facture = models.FileField(upload_to=facture_path, blank=True, null=True)

    def __str__(self):
        return self.nom

    def facture_name(self):
        return self.facture.name.split('/')[-1]





@receiver(models.signals.post_save, sender=Transaction)
def execute_after_save(sender, instance, created, *args, **kwargs):
    if created:
        ## transac number
        Meta_Stuff.increment_lastnumber()

        ## current Compte/budget
        c = Compte.objects.get(nom=instance.compte)
        c.somme_actuelle += instance.somme  # change field
        c.save()  # this will update only
        if  instance.budget:
            b = Budget.objects.get(nom=instance.budget)
            b.somme_actuelle += instance.somme  # change field
            b.save()  # this will update only

@receiver(models.signals.pre_delete, sender=Transaction)
def execute_before_delete(sender, instance, using, *args, **kwargs):
    ## transac number
    Meta_Stuff.decrement_lastnumber()

    ## current Compte/budget
    c = Compte.objects.get(nom=instance.compte)
    c.somme_actuelle -= instance.somme  # change field
    c.save()  # this will update only
    if instance.budget:
        b = Budget.objects.get(nom=instance.budget)
        b.somme_actuelle -= instance.somme  # change field
        b.save()  # this will update only

当数据库是 sqlite 时它可以工作,但后来我决定迁移到 PostgreSQL。然后,我遇到了这个错误:

>python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, compta, contenttypes, sessions
Running migrations:
  Applying compta.0011_auto_20180119_1119...Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "D:\Anaconda\envs\compta\lib\site-packages\django\core\management\__init__.py", line 364, in execute_from_command_line
utility.execute()
  File "D:\Anaconda\envs\compta\lib\site-packages\django\core\management\__init__.py", line 356, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
  File "D:\Anaconda\envs\compta\lib\site-packages\django\core\management\base.py", line 283, in run_from_argv
self.execute(*args, **cmd_options)
  File "D:\Anaconda\envs\compta\lib\site-packages\django\core\management\base.py", line 330, in execute
output = self.handle(*args, **options)
  File "D:\Anaconda\envs\compta\lib\site-packages\django\core\management\commands\migrate.py", line 204, in handle
fake_initial=fake_initial,
  File "D:\Anaconda\envs\compta\lib\site-packages\django\db\migrations\executor.py", line 115, in migrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "D:\Anaconda\envs\compta\lib\site-packages\django\db\migrations\executor.py", line 145, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "D:\Anaconda\envs\compta\lib\site-packages\django\db\migrations\executor.py", line 244, in apply_migration
state = migration.apply(state, schema_editor)
  File "D:\Anaconda\envs\compta\lib\site-packages\django\db\migrations\migration.py", line 129, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "D:\Anaconda\envs\compta\lib\site-packages\django\db\migrations\operations\fields.py", line 216, in database_forwards
schema_editor.alter_field(from_model, from_field, to_field)
  File "D:\Anaconda\envs\compta\lib\site-packages\django\db\backends\base\schema.py", line 515, in alter_field
old_db_params, new_db_params, strict)
  File "D:\Anaconda\envs\compta\lib\site-packages\django\db\backends\postgresql\schema.py", line 112, in _alter_field
new_db_params, strict,
  File "D:\Anaconda\envs\compta\lib\site-packages\django\db\backends\base\schema.py", line 613, in _alter_field
new_default = self.effective_default(new_field)
  File "D:\Anaconda\envs\compta\lib\site-packages\django\db\backends\base\schema.py", line 207, in effective_default
default = field.get_default()
  File "D:\Anaconda\envs\compta\lib\site-packages\django\db\models\fields\__init__.py", line 782, in get_default
return self._get_default()
  File "D:\Projets\aesc_compta\compta\models.py", line 44, in get_lastnumber
return cls.objects.get(pk=1).transac_number
  File "D:\Anaconda\envs\compta\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "D:\Anaconda\envs\compta\lib\site-packages\django\db\models\query.py", line 380, in get
self.model._meta.object_name
compta.models.DoesNotExist: Meta_Stuff matching query does not exist.

据我了解,当我尝试迁移数据库时,它会尝试获取 with 的实例,Meta_Stuffpk=1由于它不存在而引发错误。这是正常的,因为数据库中还没有任何内容。

老实说,我对此有点迷茫。

感谢您的时间。

标签: pythondjangodjango-models

解决方案


我终于找到了解决办法!

我只需要添加初始数据 python manage.py loaddata <initial data file>

最初,我认为migrate在加载初始数据之前我需要这样做,但显然不是。这可能是因为我已经进行了一些迁移(使用 sqlite 数据库完成)。


推荐阅读