使用django / postgres自动增加自然键

时间:2014-11-03 14:46:03

标签: python django postgresql

让我先说一下,我是一个UI开发人员,正试图扩展到更多的后端编码,所以请原谅我,如果我的措辞完全没有。这可能是重复的,但我不确定在上帝的绿色地球上我甚至应该称之为我想做的事。


基本上,我有类别和图像。我需要用它所属类别的首字母缩写标记每个图像,并在之后增加一个sku。

例如,以下图像会自动标记为...

ABC-1
ABC-2
DEF-1
DEF-2
DEF-3
ABC-3*

* note :我希望它根据类别增加ID,而不是图片总数

我如何在惯用的Django中实现这一目标?

型号:

class Group(models.Model):
    title       = models.CharField(max_length=200)
    abbv        = models.CharField(max_length=200)
    urlified    = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    hidden      = models.BooleanField()

    def __unicode__(self):
        return self.title

class Photo(models.Model):
    group       = models.ForeignKey(Group)
    title       = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    pub_date    = models.DateTimeField(auto_now_add = True, blank=True)
    image       = models.ImageField(max_length=100)

    class Meta:
        ordering = ('pub_date',)

2 个答案:

答案 0 :(得分:3)

如果您想要真正的组合主键,您可能希望使用django-compositepks,但这并不理想。你可能最好打破DRY并记录号码(参见category_auto_key字段和默认值)。

交易将以这种方式解决:

from django.db import transaction

class Group(models.model):
    # your fields
    img_count = models.IntegerField()

    @transaction.atomic
    def next_sku(self):
        self.img_count += 1
        self.save()
        return self.img_count

class Photo(models.Model):
    # your fields
    category_auto_key = models.IntegerField(editable=False)

    def category_image(self):
        return self.group.abbv+"-"+str(self.category_auto_key)

    def save(self, *args, **kwargs):
        if not self.category_auto_key:
            self.category_auto_key = self.group.next_sku()
        super(Photo, self).save(*args, **kwargs)

当您在模板中需要它时,只需将其括在双括号中:

{{ photo.category_image }}

答案 1 :(得分:1)

我很好奇你是想在文本字段中生成和存储首字母缩略词和sku,还是想要在图像类别之间创建关系?

如果是后者,我会寻找不同的方法。

如果是前者,我会为您的图像模型使用自定义的设置或保存方法(挂钩?)。它需要进行一次小的查找来计算已经存在的首字母缩略词的数量,但我不会太担心性能。

我不确定如何在Django中完全做到这一点,但看起来接受的答案效果相似。无论如何,这是我尝试在保存期间设置模型字段。请注意未经测试。

经过深入研究后,我认为Beltiras的解决方案更好

class Photo(models.Model):
    # simple column definitions
    group       = models.ForeignKey(Group)
    title       = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    pub_date    = models.DateTimeField(auto_now_add = True, blank=True)
    image       = models.ImageField(max_length=100)

    # new column for storing abbv sku
    category_label = models.CharField(max_length=200)

    # save override
    def save(self, *args, **kwargs):
        # hopefully only set category_label on first save, not sure this
        # works, open to other ideas
        if (self.pk is None):
            count = Photo.objects.filter(group=self.group).count()
            label = self.group.abbv + '-' + count
            setattr(self, 'category_label', label)

        # call the super class' save method
        super(Photo, self).save(*args, ** kwargs)

我最不确定的部分是:

count = Photo.objects.filter(group=self.group).count()

我们的想法是在照片表中查询同一组中的照片并对其进行计数。这可能需要用直接SQL调用替换或以其他方式完成。让我知道你发现了什么。