Jim
Jim

Reputation: 829

how to update one db when another db insert a record?

I use django admin site,there are two tables, one is Category which has a totalitems column storing total number articles of this category ,the other is Article,Article has a foreign key reference Category,when i create a new article in admin site,then an update should increment the Category totalitems,i failed in this way:

models.py

class Category(models.Model):
    #id = models.IntegerField(primary_key=True,help_text='primary key',auto_created=True)
    name = models.CharField(max_length=50,help_text='category name')
    description = models.TextField(default='',help_text='category description')
    coverimg = models.CharField(max_length=200,default='',help_text='category front cover image')
    covercolor = models.CharField(max_length=7,default='#ffffff',help_text='color for each category background')
    totalitems = models.IntegerField(default=0,help_text='total items for each category')
    createtime = models.DateTimeField(auto_now_add=True)
    modifytime = models.DateTimeField(auto_now=True)

    categories = models.Manager()

    class Meta:
        db_table = 'article_category'
    def __str__(self):
        return self.name

#blog article models
class Article(models.Model):
    STATUS = (
        (0,'on'),
        (1,'off')
    )
    #id = models.IntegerField(primary_key=True,help_text='primary key',auto_created=True)
    category = models.ForeignKey(Category,related_name='articles', help_text='foreigner key reference Category')
    #author = models.ForeignKey(myadmin.User, help_text='foreigner key reference myadmin User')
    title = models.CharField(max_length=100, help_text='article title')
    description = models.TextField(help_text='article brief description')
    content = models.TextField(help_text='article content')
    like = models.IntegerField(default=0,help_text='like numbers')
    secretcode = models.CharField(max_length=512,help_text='who has the code can scan')
    status = models.IntegerField(choices=STATUS,help_text='status of the article')
    createtime = models.DateTimeField(auto_now_add=True,help_text='time that first created')
    modifytime = models.DateTimeField(auto_now=True,help_text='time when modified')

    articles = models.Manager()

    def __str__(self):
        return self.title
    class Meta:
        db_table = 'article'

    def save(self, *args, **kwargs):
        if not self.id:
            Category.categories.filter(articles=Article).update(totalitems = F('totalitems')+1)
        super(Article,self).save(*args, **kwargs)

although the sql operation succeed,but the column totalitems not updated,where i was doing wrong? and where is the best place to automatically updated affected models,in Model or in django AdminSite?

Upvotes: 2

Views: 52

Answers (2)

Dwight Gunning
Dwight Gunning

Reputation: 2525

Providing an answer that offers an alternative approach as requested in the question comments.

Instead of persisting a 'calculated field', calculate it when needed at runtime via a total_items() function on the Category class.

class Category(models.Model):
    #id = models.IntegerField(primary_key=True,help_text='primary key',auto_created=True)
    name = models.CharField(max_length=50,help_text='category name')
    description = models.TextField(default='',help_text='category description')
    coverimg = models.CharField(max_length=200,default='',help_text='category front cover image')
    covercolor = models.CharField(max_length=7,default='#ffffff',help_text='color for each category background')
    createtime = models.DateTimeField(auto_now_add=True)
    modifytime = models.DateTimeField(auto_now=True)

    categories = models.Manager()

    class Meta:
        db_table = 'article_category'

    def __str__(self):
        return self.name

    def total_items(self):
        return Articles.objects.filter(category=self).count()

Upvotes: 1

catavaran
catavaran

Reputation: 45575

Change the filter expression:

Category.categories.filter(pk=self.category.pk).update(
                                            totalitems = F('totalitems') + 1)

But anyway you will have wrong totalitems count in case of deletion of Article. Changing the article's category will lead to invalid total count too.

Upvotes: 2

Related Questions