We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[Propuesta] Al momento de ser publicada no se envíá automáticamente a los candidatos.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `popular_proposal/models.py`
Content:
```
1 # coding=utf-8
2 from __future__ import unicode_literals
3 
4 from django.db import models
5 from picklefield.fields import PickledObjectField
6 from django.contrib.auth.models import User
7 from djchoices import DjangoChoices, ChoiceItem
8 from votainteligente.send_mails import send_mail
9 from django.utils.encoding import python_2_unicode_compatible
10 from django.contrib.sites.models import Site
11 from autoslug import AutoSlugField
12 from django.core.urlresolvers import reverse
13 from backend_citizen.models import Organization
14 from votainteligente.open_graph import OGPMixin
15 from elections.models import Candidate, Area
16 from django.db.models import Count
17 from django.utils.translation import ugettext_lazy as _
18 from django.conf import settings
19 from django.core.mail import mail_admins
20 
21 
22 class NeedingModerationManager(models.Manager):
23     def get_queryset(self):
24         qs = super(NeedingModerationManager, self).get_queryset()
25         qs = qs.filter(status=ProposalTemporaryData.Statuses.InOurSide)
26         return qs
27 
28 
29 class ProposalCreationMixin(object):
30     def determine_kwargs(self, **kwargs):
31             model = kwargs.pop('model_class', self.__class__)
32             for f in model._meta.fields:
33                 if f.name in kwargs['data'].keys():
34                     kwargs[f.name] = kwargs['data'].pop(f.name)
35             return kwargs
36 
37 
38 @python_2_unicode_compatible
39 class ProposalTemporaryData(models.Model, ProposalCreationMixin):
40     class Statuses(DjangoChoices):
41         InOurSide = ChoiceItem('in_our_side')
42         InTheirSide = ChoiceItem('in_their_side')
43         Rejected = ChoiceItem('rejected')
44         Accepted = ChoiceItem('accepted')
45     proposer = models.ForeignKey(User, related_name='temporary_proposals')
46     area = models.ForeignKey(Area, related_name='temporary_proposals', null=True, blank=True)
47     join_advocacy_url = models.URLField(null=True, blank=True)
48     data = PickledObjectField()
49     rejected = models.BooleanField(default=False)
50     rejected_reason = models.TextField(null=True,
51                                        blank=True)
52     organization = models.ForeignKey(Organization,
53                                      related_name='temporary_proposals',
54                                      null=True,
55                                      blank=True,
56                                      default=None)
57     comments = PickledObjectField()
58     status = models.CharField(max_length=16,
59                               choices=Statuses.choices,
60                               validators=[Statuses.validator],
61                               default=Statuses.InOurSide)
62     overall_comments = models.CharField(max_length=512,
63                                         blank=True,
64                                         null=True,
65                                         default="")
66     created = models.DateTimeField(auto_now_add=True,
67                                    blank=True,
68                                    null=True)
69     updated = models.DateTimeField(auto_now=True,
70                                    blank=True,
71                                    null=True)
72 
73     needing_moderation = NeedingModerationManager()
74     objects = models.Manager()
75 
76     def save(self, *args, **kwargs):
77         creating = self.id is None
78         if not self.comments:
79             self.comments = {}
80         for key in self.data.keys():
81             if key not in self.comments.keys():
82                 self.comments[key] = ''
83         return super(ProposalTemporaryData, self).save(*args, **kwargs)
84 
85     def notify_new(self):
86         site = Site.objects.get_current()
87         mail_context = {
88             'area': self.area,
89             'temporary_data': self,
90             'site': site,
91         }
92         if self.proposer.email:
93             send_mail(mail_context, 'new_temporary_proposal',
94                       to=[self.proposer.email])
95 
96     def create_proposal(self, moderator=None):
97         self.status = ProposalTemporaryData.Statuses.Accepted
98         self.save()
99         title = self.get_title()
100         clasification = self.data.get('clasification', '')
101         org_id = self.data.pop('organization', None)
102 
103         creation_kwargs = self.determine_kwargs(title=title,
104                                                 clasification=clasification,
105                                                 area=self.area,
106                                                 proposer=self.proposer,
107                                                 data=self.data,
108                                                 temporary=self)
109         popular_proposal = PopularProposal(**creation_kwargs)
110         if org_id:
111             enrollment = self.proposer.enrollments.get(organization__id=org_id)
112             popular_proposal.organization = enrollment.organization
113         popular_proposal.save()
114         site = Site.objects.get_current()
115         mail_context = {
116             'area': self.area,
117             'temporary_data': self,
118             'moderator': moderator,
119             'site': site,
120         }
121         send_mail(mail_context, 'popular_proposal_accepted', to=[self.proposer.email])
122         return popular_proposal
123 
124     def reject(self, reason, moderator=None):
125         self.rejected_reason = reason
126         self.status = ProposalTemporaryData.Statuses.Rejected
127         self.save()
128         site = Site.objects.get_current()
129         mail_context = {
130             'area': self.area,
131             'temporary_data': self,
132             'moderator': moderator,
133             'site': site,
134         }
135         send_mail(mail_context, 'popular_proposal_rejected',
136                   to=[self.proposer.email])
137 
138     def get_title(self):
139         return self.data.get('title', u'')
140 
141     def __str__(self):
142         return self.get_title()
143 
144 class ProposalsOrderedManager(models.Manager):
145     def by_likers(self, *args, **kwargs):
146         qs = self.get_queryset()
147         qs = qs.annotate(num_likers=Count('likers')).order_by('-num_likers')
148         return qs
149 
150 
151 @python_2_unicode_compatible
152 class PopularProposal(models.Model, OGPMixin):
153     title = models.CharField(max_length=255, default='')
154     slug = AutoSlugField(populate_from='title', unique=True)
155     proposer = models.ForeignKey(User, related_name='proposals')
156     area = models.ForeignKey(Area, related_name='proposals', null=True, blank=True)
157     join_advocacy_url = models.URLField(null=True, blank=True)
158     data = PickledObjectField()
159     created = models.DateTimeField(auto_now_add=True)
160     updated = models.DateTimeField(auto_now_add=True)
161     temporary = models.OneToOneField(ProposalTemporaryData,
162                                      related_name='created_proposal',
163                                      blank=True,
164                                      null=True,
165                                      default=None)
166     likers = models.ManyToManyField(User, through='ProposalLike')
167     organization = models.ForeignKey(Organization,
168                                      related_name='popular_proposals',
169                                      null=True)
170     background = models.TextField(null=True, blank=True, help_text=_(u"Antecedentes sobre tu propuesta"))
171     contact_details = models.TextField(null=True,
172                                        blank=True,
173                                        help_text=_(u'¿Cómo te puede contactar un candidato?'))
174     document = models.FileField(upload_to='uploads/proposal/backgrounds/%Y/%m/%d/',
175                                 help_text=_(u'¿Tienes algún documento para complementar tu propuesta?'),
176                                 null=True,
177                                 blank=True)
178     image = models.ImageField(upload_to='proposals/image/',
179                               max_length=512,
180                               null=True,
181                               blank=True)
182     clasification = models.CharField(blank=True, null=True, max_length=255)
183     for_all_areas = models.BooleanField(default=False)
184 
185     ogp_enabled = True
186 
187     ordered = ProposalsOrderedManager()
188     objects = models.Manager()
189 
190     class Meta:
191         ordering = ['for_all_areas', '-created']
192 
193     def __str__(self):
194         return self.title
195 
196     def get_absolute_url(self):
197         return reverse('popular_proposals:detail', kwargs={'slug': self.slug})
198 
199     def save(self, *args, **kwargs):
200         creating = self.pk is None
201         super(PopularProposal, self).save(*args, **kwargs)
202         if self.pk is not None and creating:
203             self.notify_candidates_of_new()
204 
205     def notify_candidates_of_new(self):
206         if not (settings.NOTIFY_CANDIDATES and settings.NOTIFY_CANDIDATES_OF_NEW_PROPOSAL):
207             return
208         template = 'notification_for_candidates_of_new_proposal'
209         context = {'proposal': self}
210         area = Area.objects.get(id=self.area.id)
211         for election in area.elections.all():
212             for candidate in election.candidates.all():
213                 for contact in candidate.contacts.all():
214                     context.update({'candidate': candidate})
215                     send_mail(context,
216                               template,
217                               to=[contact.mail])
218 
219 class ProposalLike(models.Model):
220     user = models.ForeignKey(User)
221     proposal = models.ForeignKey(PopularProposal)
222     created = models.DateTimeField(auto_now_add=True)
223     updated = models.DateTimeField(auto_now_add=True)
224 
225     def save(self, *args, **kwargs):
226         super(ProposalLike, self).save(*args, **kwargs)
227         created = self.pk is not None
228         if created:
229             self.numerical_notification()
230 
231     def numerical_notification(self):
232         the_number = ProposalLike.objects.filter(proposal=self.proposal).count()
233         if the_number in settings.WHEN_TO_NOTIFY:
234             from popular_proposal.subscriptions import YouAreAHeroNotification, ManyCitizensSupportingNotification
235             notifier = YouAreAHeroNotification(proposal=self.proposal,
236                                                number=the_number)
237             notifier.notify()
238             notifier = ManyCitizensSupportingNotification(proposal=self.proposal,
239                                                           number=the_number)
240             notifier.notify()
241 
242 
243 class Commitment(models.Model):
244     proposal = models.ForeignKey(PopularProposal,
245                                  related_name='commitments')
246     candidate = models.ForeignKey(Candidate,
247                                   related_name='commitments')
248     detail = models.CharField(max_length=12288,
249                               null=True,
250                               blank=True)
251     commited = models.NullBooleanField(default=None)
252 
253     def save(self, *args, **kwargs):
254         instance = super(Commitment, self).save(*args, **kwargs)
255         from popular_proposal.subscriptions import notification_trigger
256         notification_trigger('new-commitment',
257                              proposal=self.proposal,
258                              commitment=self)
259         return instance
260 
261     def get_absolute_url(self):
262         url = reverse('popular_proposals:commitment', kwargs={'candidate_slug': self.candidate.id,
263                                                               'proposal_slug': self.proposal.slug})
264         return url
265
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/popular_proposal/models.py b/popular_proposal/models.py
--- a/popular_proposal/models.py
+++ b/popular_proposal/models.py
@@ -196,12 +196,6 @@
     def get_absolute_url(self):
         return reverse('popular_proposals:detail', kwargs={'slug': self.slug})
 
-    def save(self, *args, **kwargs):
-        creating = self.pk is None
-        super(PopularProposal, self).save(*args, **kwargs)
-        if self.pk is not None and creating:
-            self.notify_candidates_of_new()
-
     def notify_candidates_of_new(self):
         if not (settings.NOTIFY_CANDIDATES and settings.NOTIFY_CANDIDATES_OF_NEW_PROPOSAL):
             return

{"golden_diff": "diff --git a/popular_proposal/models.py b/popular_proposal/models.py\n--- a/popular_proposal/models.py\n+++ b/popular_proposal/models.py\n@@ -196,12 +196,6 @@\n     def get_absolute_url(self):\n         return reverse('popular_proposals:detail', kwargs={'slug': self.slug})\n \n-    def save(self, *args, **kwargs):\n-        creating = self.pk is None\n-        super(PopularProposal, self).save(*args, **kwargs)\n-        if self.pk is not None and creating:\n-            self.notify_candidates_of_new()\n-\n     def notify_candidates_of_new(self):\n         if not (settings.NOTIFY_CANDIDATES and settings.NOTIFY_CANDIDATES_OF_NEW_PROPOSAL):\n             return\n", "issue": "[Propuesta] Al momento de ser publicada no se env\u00ed\u00e1 autom\u00e1ticamente a los candidatos.\n\n", "before_files": [{"content": "# coding=utf-8\nfrom __future__ import unicode_literals\n\nfrom django.db import models\nfrom picklefield.fields import PickledObjectField\nfrom django.contrib.auth.models import User\nfrom djchoices import DjangoChoices, ChoiceItem\nfrom votainteligente.send_mails import send_mail\nfrom django.utils.encoding import python_2_unicode_compatible\nfrom django.contrib.sites.models import Site\nfrom autoslug import AutoSlugField\nfrom django.core.urlresolvers import reverse\nfrom backend_citizen.models import Organization\nfrom votainteligente.open_graph import OGPMixin\nfrom elections.models import Candidate, Area\nfrom django.db.models import Count\nfrom django.utils.translation import ugettext_lazy as _\nfrom django.conf import settings\nfrom django.core.mail import mail_admins\n\n\nclass NeedingModerationManager(models.Manager):\n    def get_queryset(self):\n        qs = super(NeedingModerationManager, self).get_queryset()\n        qs = qs.filter(status=ProposalTemporaryData.Statuses.InOurSide)\n        return qs\n\n\nclass ProposalCreationMixin(object):\n    def determine_kwargs(self, **kwargs):\n            model = kwargs.pop('model_class', self.__class__)\n            for f in model._meta.fields:\n                if f.name in kwargs['data'].keys():\n                    kwargs[f.name] = kwargs['data'].pop(f.name)\n            return kwargs\n\n\n@python_2_unicode_compatible\nclass ProposalTemporaryData(models.Model, ProposalCreationMixin):\n    class Statuses(DjangoChoices):\n        InOurSide = ChoiceItem('in_our_side')\n        InTheirSide = ChoiceItem('in_their_side')\n        Rejected = ChoiceItem('rejected')\n        Accepted = ChoiceItem('accepted')\n    proposer = models.ForeignKey(User, related_name='temporary_proposals')\n    area = models.ForeignKey(Area, related_name='temporary_proposals', null=True, blank=True)\n    join_advocacy_url = models.URLField(null=True, blank=True)\n    data = PickledObjectField()\n    rejected = models.BooleanField(default=False)\n    rejected_reason = models.TextField(null=True,\n                                       blank=True)\n    organization = models.ForeignKey(Organization,\n                                     related_name='temporary_proposals',\n                                     null=True,\n                                     blank=True,\n                                     default=None)\n    comments = PickledObjectField()\n    status = models.CharField(max_length=16,\n                              choices=Statuses.choices,\n                              validators=[Statuses.validator],\n                              default=Statuses.InOurSide)\n    overall_comments = models.CharField(max_length=512,\n                                        blank=True,\n                                        null=True,\n                                        default=\"\")\n    created = models.DateTimeField(auto_now_add=True,\n                                   blank=True,\n                                   null=True)\n    updated = models.DateTimeField(auto_now=True,\n                                   blank=True,\n                                   null=True)\n\n    needing_moderation = NeedingModerationManager()\n    objects = models.Manager()\n\n    def save(self, *args, **kwargs):\n        creating = self.id is None\n        if not self.comments:\n            self.comments = {}\n        for key in self.data.keys():\n            if key not in self.comments.keys():\n                self.comments[key] = ''\n        return super(ProposalTemporaryData, self).save(*args, **kwargs)\n\n    def notify_new(self):\n        site = Site.objects.get_current()\n        mail_context = {\n            'area': self.area,\n            'temporary_data': self,\n            'site': site,\n        }\n        if self.proposer.email:\n            send_mail(mail_context, 'new_temporary_proposal',\n                      to=[self.proposer.email])\n\n    def create_proposal(self, moderator=None):\n        self.status = ProposalTemporaryData.Statuses.Accepted\n        self.save()\n        title = self.get_title()\n        clasification = self.data.get('clasification', '')\n        org_id = self.data.pop('organization', None)\n\n        creation_kwargs = self.determine_kwargs(title=title,\n                                                clasification=clasification,\n                                                area=self.area,\n                                                proposer=self.proposer,\n                                                data=self.data,\n                                                temporary=self)\n        popular_proposal = PopularProposal(**creation_kwargs)\n        if org_id:\n            enrollment = self.proposer.enrollments.get(organization__id=org_id)\n            popular_proposal.organization = enrollment.organization\n        popular_proposal.save()\n        site = Site.objects.get_current()\n        mail_context = {\n            'area': self.area,\n            'temporary_data': self,\n            'moderator': moderator,\n            'site': site,\n        }\n        send_mail(mail_context, 'popular_proposal_accepted', to=[self.proposer.email])\n        return popular_proposal\n\n    def reject(self, reason, moderator=None):\n        self.rejected_reason = reason\n        self.status = ProposalTemporaryData.Statuses.Rejected\n        self.save()\n        site = Site.objects.get_current()\n        mail_context = {\n            'area': self.area,\n            'temporary_data': self,\n            'moderator': moderator,\n            'site': site,\n        }\n        send_mail(mail_context, 'popular_proposal_rejected',\n                  to=[self.proposer.email])\n\n    def get_title(self):\n        return self.data.get('title', u'')\n\n    def __str__(self):\n        return self.get_title()\n\nclass ProposalsOrderedManager(models.Manager):\n    def by_likers(self, *args, **kwargs):\n        qs = self.get_queryset()\n        qs = qs.annotate(num_likers=Count('likers')).order_by('-num_likers')\n        return qs\n\n\n@python_2_unicode_compatible\nclass PopularProposal(models.Model, OGPMixin):\n    title = models.CharField(max_length=255, default='')\n    slug = AutoSlugField(populate_from='title', unique=True)\n    proposer = models.ForeignKey(User, related_name='proposals')\n    area = models.ForeignKey(Area, related_name='proposals', null=True, blank=True)\n    join_advocacy_url = models.URLField(null=True, blank=True)\n    data = PickledObjectField()\n    created = models.DateTimeField(auto_now_add=True)\n    updated = models.DateTimeField(auto_now_add=True)\n    temporary = models.OneToOneField(ProposalTemporaryData,\n                                     related_name='created_proposal',\n                                     blank=True,\n                                     null=True,\n                                     default=None)\n    likers = models.ManyToManyField(User, through='ProposalLike')\n    organization = models.ForeignKey(Organization,\n                                     related_name='popular_proposals',\n                                     null=True)\n    background = models.TextField(null=True, blank=True, help_text=_(u\"Antecedentes sobre tu propuesta\"))\n    contact_details = models.TextField(null=True,\n                                       blank=True,\n                                       help_text=_(u'\u00bfC\u00f3mo te puede contactar un candidato?'))\n    document = models.FileField(upload_to='uploads/proposal/backgrounds/%Y/%m/%d/',\n                                help_text=_(u'\u00bfTienes alg\u00fan documento para complementar tu propuesta?'),\n                                null=True,\n                                blank=True)\n    image = models.ImageField(upload_to='proposals/image/',\n                              max_length=512,\n                              null=True,\n                              blank=True)\n    clasification = models.CharField(blank=True, null=True, max_length=255)\n    for_all_areas = models.BooleanField(default=False)\n\n    ogp_enabled = True\n\n    ordered = ProposalsOrderedManager()\n    objects = models.Manager()\n\n    class Meta:\n        ordering = ['for_all_areas', '-created']\n\n    def __str__(self):\n        return self.title\n\n    def get_absolute_url(self):\n        return reverse('popular_proposals:detail', kwargs={'slug': self.slug})\n\n    def save(self, *args, **kwargs):\n        creating = self.pk is None\n        super(PopularProposal, self).save(*args, **kwargs)\n        if self.pk is not None and creating:\n            self.notify_candidates_of_new()\n\n    def notify_candidates_of_new(self):\n        if not (settings.NOTIFY_CANDIDATES and settings.NOTIFY_CANDIDATES_OF_NEW_PROPOSAL):\n            return\n        template = 'notification_for_candidates_of_new_proposal'\n        context = {'proposal': self}\n        area = Area.objects.get(id=self.area.id)\n        for election in area.elections.all():\n            for candidate in election.candidates.all():\n                for contact in candidate.contacts.all():\n                    context.update({'candidate': candidate})\n                    send_mail(context,\n                              template,\n                              to=[contact.mail])\n\nclass ProposalLike(models.Model):\n    user = models.ForeignKey(User)\n    proposal = models.ForeignKey(PopularProposal)\n    created = models.DateTimeField(auto_now_add=True)\n    updated = models.DateTimeField(auto_now_add=True)\n\n    def save(self, *args, **kwargs):\n        super(ProposalLike, self).save(*args, **kwargs)\n        created = self.pk is not None\n        if created:\n            self.numerical_notification()\n\n    def numerical_notification(self):\n        the_number = ProposalLike.objects.filter(proposal=self.proposal).count()\n        if the_number in settings.WHEN_TO_NOTIFY:\n            from popular_proposal.subscriptions import YouAreAHeroNotification, ManyCitizensSupportingNotification\n            notifier = YouAreAHeroNotification(proposal=self.proposal,\n                                               number=the_number)\n            notifier.notify()\n            notifier = ManyCitizensSupportingNotification(proposal=self.proposal,\n                                                          number=the_number)\n            notifier.notify()\n\n\nclass Commitment(models.Model):\n    proposal = models.ForeignKey(PopularProposal,\n                                 related_name='commitments')\n    candidate = models.ForeignKey(Candidate,\n                                  related_name='commitments')\n    detail = models.CharField(max_length=12288,\n                              null=True,\n                              blank=True)\n    commited = models.NullBooleanField(default=None)\n\n    def save(self, *args, **kwargs):\n        instance = super(Commitment, self).save(*args, **kwargs)\n        from popular_proposal.subscriptions import notification_trigger\n        notification_trigger('new-commitment',\n                             proposal=self.proposal,\n                             commitment=self)\n        return instance\n\n    def get_absolute_url(self):\n        url = reverse('popular_proposals:commitment', kwargs={'candidate_slug': self.candidate.id,\n                                                              'proposal_slug': self.proposal.slug})\n        return url\n", "path": "popular_proposal/models.py"}], "after_files": [{"content": "# coding=utf-8\nfrom __future__ import unicode_literals\n\nfrom django.db import models\nfrom picklefield.fields import PickledObjectField\nfrom django.contrib.auth.models import User\nfrom djchoices import DjangoChoices, ChoiceItem\nfrom votainteligente.send_mails import send_mail\nfrom django.utils.encoding import python_2_unicode_compatible\nfrom django.contrib.sites.models import Site\nfrom autoslug import AutoSlugField\nfrom django.core.urlresolvers import reverse\nfrom backend_citizen.models import Organization\nfrom votainteligente.open_graph import OGPMixin\nfrom elections.models import Candidate, Area\nfrom django.db.models import Count\nfrom django.utils.translation import ugettext_lazy as _\nfrom django.conf import settings\nfrom django.core.mail import mail_admins\n\n\nclass NeedingModerationManager(models.Manager):\n    def get_queryset(self):\n        qs = super(NeedingModerationManager, self).get_queryset()\n        qs = qs.filter(status=ProposalTemporaryData.Statuses.InOurSide)\n        return qs\n\n\nclass ProposalCreationMixin(object):\n    def determine_kwargs(self, **kwargs):\n            model = kwargs.pop('model_class', self.__class__)\n            for f in model._meta.fields:\n                if f.name in kwargs['data'].keys():\n                    kwargs[f.name] = kwargs['data'].pop(f.name)\n            return kwargs\n\n\n@python_2_unicode_compatible\nclass ProposalTemporaryData(models.Model, ProposalCreationMixin):\n    class Statuses(DjangoChoices):\n        InOurSide = ChoiceItem('in_our_side')\n        InTheirSide = ChoiceItem('in_their_side')\n        Rejected = ChoiceItem('rejected')\n        Accepted = ChoiceItem('accepted')\n    proposer = models.ForeignKey(User, related_name='temporary_proposals')\n    area = models.ForeignKey(Area, related_name='temporary_proposals', null=True, blank=True)\n    join_advocacy_url = models.URLField(null=True, blank=True)\n    data = PickledObjectField()\n    rejected = models.BooleanField(default=False)\n    rejected_reason = models.TextField(null=True,\n                                       blank=True)\n    organization = models.ForeignKey(Organization,\n                                     related_name='temporary_proposals',\n                                     null=True,\n                                     blank=True,\n                                     default=None)\n    comments = PickledObjectField()\n    status = models.CharField(max_length=16,\n                              choices=Statuses.choices,\n                              validators=[Statuses.validator],\n                              default=Statuses.InOurSide)\n    overall_comments = models.CharField(max_length=512,\n                                        blank=True,\n                                        null=True,\n                                        default=\"\")\n    created = models.DateTimeField(auto_now_add=True,\n                                   blank=True,\n                                   null=True)\n    updated = models.DateTimeField(auto_now=True,\n                                   blank=True,\n                                   null=True)\n\n    needing_moderation = NeedingModerationManager()\n    objects = models.Manager()\n\n    def save(self, *args, **kwargs):\n        creating = self.id is None\n        if not self.comments:\n            self.comments = {}\n        for key in self.data.keys():\n            if key not in self.comments.keys():\n                self.comments[key] = ''\n        return super(ProposalTemporaryData, self).save(*args, **kwargs)\n\n    def notify_new(self):\n        site = Site.objects.get_current()\n        mail_context = {\n            'area': self.area,\n            'temporary_data': self,\n            'site': site,\n        }\n        if self.proposer.email:\n            send_mail(mail_context, 'new_temporary_proposal',\n                      to=[self.proposer.email])\n\n    def create_proposal(self, moderator=None):\n        self.status = ProposalTemporaryData.Statuses.Accepted\n        self.save()\n        title = self.get_title()\n        clasification = self.data.get('clasification', '')\n        org_id = self.data.pop('organization', None)\n\n        creation_kwargs = self.determine_kwargs(title=title,\n                                                clasification=clasification,\n                                                area=self.area,\n                                                proposer=self.proposer,\n                                                data=self.data,\n                                                temporary=self)\n        popular_proposal = PopularProposal(**creation_kwargs)\n        if org_id:\n            enrollment = self.proposer.enrollments.get(organization__id=org_id)\n            popular_proposal.organization = enrollment.organization\n        popular_proposal.save()\n        site = Site.objects.get_current()\n        mail_context = {\n            'area': self.area,\n            'temporary_data': self,\n            'moderator': moderator,\n            'site': site,\n        }\n        send_mail(mail_context, 'popular_proposal_accepted', to=[self.proposer.email])\n        return popular_proposal\n\n    def reject(self, reason, moderator=None):\n        self.rejected_reason = reason\n        self.status = ProposalTemporaryData.Statuses.Rejected\n        self.save()\n        site = Site.objects.get_current()\n        mail_context = {\n            'area': self.area,\n            'temporary_data': self,\n            'moderator': moderator,\n            'site': site,\n        }\n        send_mail(mail_context, 'popular_proposal_rejected',\n                  to=[self.proposer.email])\n\n    def get_title(self):\n        return self.data.get('title', u'')\n\n    def __str__(self):\n        return self.get_title()\n\nclass ProposalsOrderedManager(models.Manager):\n    def by_likers(self, *args, **kwargs):\n        qs = self.get_queryset()\n        qs = qs.annotate(num_likers=Count('likers')).order_by('-num_likers')\n        return qs\n\n\n@python_2_unicode_compatible\nclass PopularProposal(models.Model, OGPMixin):\n    title = models.CharField(max_length=255, default='')\n    slug = AutoSlugField(populate_from='title', unique=True)\n    proposer = models.ForeignKey(User, related_name='proposals')\n    area = models.ForeignKey(Area, related_name='proposals', null=True, blank=True)\n    join_advocacy_url = models.URLField(null=True, blank=True)\n    data = PickledObjectField()\n    created = models.DateTimeField(auto_now_add=True)\n    updated = models.DateTimeField(auto_now_add=True)\n    temporary = models.OneToOneField(ProposalTemporaryData,\n                                     related_name='created_proposal',\n                                     blank=True,\n                                     null=True,\n                                     default=None)\n    likers = models.ManyToManyField(User, through='ProposalLike')\n    organization = models.ForeignKey(Organization,\n                                     related_name='popular_proposals',\n                                     null=True)\n    background = models.TextField(null=True, blank=True, help_text=_(u\"Antecedentes sobre tu propuesta\"))\n    contact_details = models.TextField(null=True,\n                                       blank=True,\n                                       help_text=_(u'\u00bfC\u00f3mo te puede contactar un candidato?'))\n    document = models.FileField(upload_to='uploads/proposal/backgrounds/%Y/%m/%d/',\n                                help_text=_(u'\u00bfTienes alg\u00fan documento para complementar tu propuesta?'),\n                                null=True,\n                                blank=True)\n    image = models.ImageField(upload_to='proposals/image/',\n                              max_length=512,\n                              null=True,\n                              blank=True)\n    clasification = models.CharField(blank=True, null=True, max_length=255)\n    for_all_areas = models.BooleanField(default=False)\n\n    ogp_enabled = True\n\n    ordered = ProposalsOrderedManager()\n    objects = models.Manager()\n\n    class Meta:\n        ordering = ['for_all_areas', '-created']\n\n    def __str__(self):\n        return self.title\n\n    def get_absolute_url(self):\n        return reverse('popular_proposals:detail', kwargs={'slug': self.slug})\n\n    def notify_candidates_of_new(self):\n        if not (settings.NOTIFY_CANDIDATES and settings.NOTIFY_CANDIDATES_OF_NEW_PROPOSAL):\n            return\n        template = 'notification_for_candidates_of_new_proposal'\n        context = {'proposal': self}\n        area = Area.objects.get(id=self.area.id)\n        for election in area.elections.all():\n            for candidate in election.candidates.all():\n                for contact in candidate.contacts.all():\n                    context.update({'candidate': candidate})\n                    send_mail(context,\n                              template,\n                              to=[contact.mail])\n\nclass ProposalLike(models.Model):\n    user = models.ForeignKey(User)\n    proposal = models.ForeignKey(PopularProposal)\n    created = models.DateTimeField(auto_now_add=True)\n    updated = models.DateTimeField(auto_now_add=True)\n\n    def save(self, *args, **kwargs):\n        super(ProposalLike, self).save(*args, **kwargs)\n        created = self.pk is not None\n        if created:\n            self.numerical_notification()\n\n    def numerical_notification(self):\n        the_number = ProposalLike.objects.filter(proposal=self.proposal).count()\n        if the_number in settings.WHEN_TO_NOTIFY:\n            from popular_proposal.subscriptions import YouAreAHeroNotification, ManyCitizensSupportingNotification\n            notifier = YouAreAHeroNotification(proposal=self.proposal,\n                                               number=the_number)\n            notifier.notify()\n            notifier = ManyCitizensSupportingNotification(proposal=self.proposal,\n                                                          number=the_number)\n            notifier.notify()\n\n\nclass Commitment(models.Model):\n    proposal = models.ForeignKey(PopularProposal,\n                                 related_name='commitments')\n    candidate = models.ForeignKey(Candidate,\n                                  related_name='commitments')\n    detail = models.CharField(max_length=12288,\n                              null=True,\n                              blank=True)\n    commited = models.NullBooleanField(default=None)\n\n    def save(self, *args, **kwargs):\n        instance = super(Commitment, self).save(*args, **kwargs)\n        from popular_proposal.subscriptions import notification_trigger\n        notification_trigger('new-commitment',\n                             proposal=self.proposal,\n                             commitment=self)\n        return instance\n\n    def get_absolute_url(self):\n        url = reverse('popular_proposals:commitment', kwargs={'candidate_slug': self.candidate.id,\n                                                              'proposal_slug': self.proposal.slug})\n        return url\n", "path": "popular_proposal/models.py"}]}