Code

Ticket #5390: models.py

File models.py, 3.0 KB (added by Ludovico Magnocavallo <ludo@…>, 7 years ago)

Test models

Line 
1from django.db import models
2from django.db.models import signals
3from django.dispatch import dispatcher
4
5class Category(models.Model):
6    name = models.CharField(maxlength=32)
7    post_count = models.IntegerField(blank=True, default=0)
8   
9    def __unicode__(self):
10        return u"<Category %s '%s' (%s)>" % (self.id, self.name, self.post_count)
11   
12    def __repr__(self):
13        return self.__unicode__()
14   
15    def _m2m_entry(self, entry, increment):
16        if not isinstance(entry, Entry):
17            entry = Entry.objects.get(pk=entry)
18        if entry.status == 'P' and (self.post_count or increment):
19            self.post_count += increment
20            self.save()
21           
22    @staticmethod
23    def m2m_entry(signal, sender, instance, objs=None):
24        if sender == Entry:
25            # instance ---> Category, objs ---> Entry
26            if signal == signals.m2m_clear_items:
27                instance.post_count = 0
28                instance.save()
29                return
30            increment = 1
31            if signal == signals.m2m_remove_items:
32                increment = -1
33            for obj in objs:
34                instance._m2m_entry(obj, increment)
35        else:
36            # instance ---> Entry, objs ---> Category
37            increment = -1
38            if signal == signals.m2m_add_items:
39                increment = 1
40            elif signal == signals.m2m_clear_items:
41                objs = list(instance.categories.all())
42            for obj in objs:
43                if not isinstance(obj, Category):
44                    obj = Category.objects.get(pk=obj)
45                obj._m2m_entry(instance, increment)
46           
47
48class Entry(models.Model):
49   
50    title = models.CharField(maxlength=64)
51    status = models.CharField(maxlength=1, blank=True, choices=(('P', 'Published'), ('D', 'Draft')), default='D')
52    categories = models.ManyToManyField(Category, blank=True, null=True)
53   
54    def __init__(self, *args, **kw):
55        super(Entry, self).__init__(*args, **kw)
56        self._status = self.status
57   
58    def __unicode__(self):
59        return u"<Post '%s'>" % self.title
60   
61    def __repr__(self):
62        return self.__unicode__()
63   
64    def save(self):
65        super(Entry, self).save()
66        if self.status == 'P' and self._status != 'P':
67            Category.m2m_entry(signals.m2m_add_items, Category, self, list(self.categories.all()))
68        elif self.status != 'P' and self._status == 'P':
69            Category.m2m_entry(signals.m2m_remove_items, Category, self, list(self.categories.all()))
70   
71
72# TODO: do not use sender
73dispatcher.connect(Category.m2m_entry, signal=signals.m2m_add_items, sender=Category)
74dispatcher.connect(Category.m2m_entry, signal=signals.m2m_remove_items, sender=Category)
75dispatcher.connect(Category.m2m_entry, signal=signals.m2m_clear_items, sender=Category)
76dispatcher.connect(Category.m2m_entry, signal=signals.m2m_add_items, sender=Entry)
77dispatcher.connect(Category.m2m_entry, signal=signals.m2m_remove_items, sender=Entry)
78dispatcher.connect(Category.m2m_entry, signal=signals.m2m_clear_items, sender=Entry)