forked from AFPy/PonyConf
Convert event from integer field to foreign key
This commit also fix conference creation for initial Site
This commit is contained in:
parent
4049841028
commit
22a0fe3ca9
|
@ -7,3 +7,4 @@ class AccountsConfig(AppConfig):
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
import accounts.signals # noqa
|
import accounts.signals # noqa
|
||||||
|
post_migrate.connect(accounts.signals.create_default_options, sender=self)
|
||||||
|
|
|
@ -2,7 +2,7 @@ from django.contrib import messages
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.auth.signals import user_logged_in, user_logged_out
|
from django.contrib.auth.signals import user_logged_in, user_logged_out
|
||||||
from django.contrib.sites.shortcuts import get_current_site
|
from django.contrib.sites.shortcuts import get_current_site
|
||||||
from django.db.models.signals import post_migrate, post_save
|
from django.db.models.signals import post_save
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.utils.translation import ugettext_noop
|
from django.utils.translation import ugettext_noop
|
||||||
|
@ -10,7 +10,6 @@ from django.utils.translation import ugettext_noop
|
||||||
from .models import Connector, Participation, Profile, Transport
|
from .models import Connector, Participation, Profile, Transport
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_migrate)
|
|
||||||
def create_default_options(sender, **kwargs):
|
def create_default_options(sender, **kwargs):
|
||||||
Transport.objects.get_or_create(name=ugettext_noop('Train'))
|
Transport.objects.get_or_create(name=ugettext_noop('Train'))
|
||||||
Transport.objects.get_or_create(name=ugettext_noop('Plane'))
|
Transport.objects.get_or_create(name=ugettext_noop('Plane'))
|
||||||
|
|
|
@ -6,7 +6,7 @@ from django.core import mail
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from accounts.models import Participation
|
from accounts.models import Participation
|
||||||
from proposals.models import Topic, Talk
|
from proposals.models import Topic, Talk, Event
|
||||||
|
|
||||||
from .models import ConversationAboutTalk, ConversationWithParticipant, Message
|
from .models import ConversationAboutTalk, ConversationWithParticipant, Message
|
||||||
|
|
||||||
|
@ -20,7 +20,8 @@ class ConversationTests(TestCase):
|
||||||
conversation, _ = ConversationWithParticipant.objects.get_or_create(participation=pa)
|
conversation, _ = ConversationWithParticipant.objects.get_or_create(participation=pa)
|
||||||
Message.objects.create(content='allo', conversation=conversation, author=b)
|
Message.objects.create(content='allo', conversation=conversation, author=b)
|
||||||
Message.objects.create(content='aluil', conversation=conversation, author=a)
|
Message.objects.create(content='aluil', conversation=conversation, author=a)
|
||||||
Talk.objects.get_or_create(site=Site.objects.first(), proposer=a, title='a talk', description='yay')
|
site = Site.objects.first()
|
||||||
|
Talk.objects.get_or_create(site=site, proposer=a, title='a talk', description='yay', event=Event.objects.get(site=site, name='other'))
|
||||||
|
|
||||||
def test_models(self):
|
def test_models(self):
|
||||||
talk, participant, message = (model.objects.first() for model in
|
talk, participant, message = (model.objects.first() for model in
|
||||||
|
|
|
@ -33,6 +33,9 @@ ALLOWED_HOSTS = []
|
||||||
# Application definition
|
# Application definition
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
|
# the post_migrate creating the first site should be call at first
|
||||||
|
'django.contrib.sites',
|
||||||
|
|
||||||
# our apps
|
# our apps
|
||||||
'accounts',
|
'accounts',
|
||||||
'ponyconf',
|
'ponyconf',
|
||||||
|
@ -53,7 +56,6 @@ INSTALLED_APPS = [
|
||||||
'django.contrib.sessions',
|
'django.contrib.sessions',
|
||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
'django.contrib.sites',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE_CLASSES = [
|
MIDDLEWARE_CLASSES = [
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
default_app_config = 'proposals.apps.ProposalsConfig'
|
|
@ -1,7 +1,23 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from proposals.models import Conference, Talk, Topic
|
from proposals.models import Conference, Talk, Topic, Event
|
||||||
|
|
||||||
|
|
||||||
|
class TalkAdmin(admin.ModelAdmin):
|
||||||
|
# Disable add button in django admin has it is too dangerous
|
||||||
|
# (it is easy to obtain incoherent data due to site framework)
|
||||||
|
def has_add_permission(self, request):
|
||||||
|
return False
|
||||||
|
# Filter for 'on site' tocpis and event
|
||||||
|
def get_form(self, request, obj=None, **kwargs):
|
||||||
|
form = super(TalkAdmin, self).get_form(request, obj, **kwargs)
|
||||||
|
# in fact, obj should never be none as 'add' button is disabled
|
||||||
|
if obj:
|
||||||
|
form.base_fields['topics'].queryset = Topic.objects.filter(site=obj.site)
|
||||||
|
form.base_fields['event'].queryset = Event.objects.filter(site=obj.site)
|
||||||
|
return form
|
||||||
|
|
||||||
admin.site.register(Conference)
|
admin.site.register(Conference)
|
||||||
admin.site.register(Topic)
|
admin.site.register(Topic)
|
||||||
admin.site.register(Talk)
|
admin.site.register(Talk, TalkAdmin)
|
||||||
|
admin.site.register(Event)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
from django.db.models.signals import post_migrate
|
||||||
|
|
||||||
|
|
||||||
class ProposalsConfig(AppConfig):
|
class ProposalsConfig(AppConfig):
|
||||||
|
@ -6,3 +7,4 @@ class ProposalsConfig(AppConfig):
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
import proposals.signals # noqa
|
import proposals.signals # noqa
|
||||||
|
post_migrate.connect(proposals.signals.call_first_site_post_save, sender=self)
|
||||||
|
|
87
proposals/migrations/0010_auto_20160822_1010.py
Normal file
87
proposals/migrations/0010_auto_20160822_1010.py
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10 on 2016-08-22 10:10
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_event(apps, schema_editor):
|
||||||
|
db_alias = schema_editor.connection.alias
|
||||||
|
# Create default Event instance, as Site post_save is not triggered
|
||||||
|
Event = apps.get_model('proposals', 'Event')
|
||||||
|
Site = apps.get_model('sites', 'Site')
|
||||||
|
for site in Site.objects.using(db_alias).all():
|
||||||
|
Event.objects.using(db_alias).bulk_create([
|
||||||
|
Event(site=site, name='conference (short)'),
|
||||||
|
Event(site=site, name='conference (long)'),
|
||||||
|
Event(site=site, name='workshop'),
|
||||||
|
Event(site=site, name='stand'),
|
||||||
|
Event(site=site, name='other'),
|
||||||
|
])
|
||||||
|
# Migrate event_old field to event field
|
||||||
|
Talk = apps.get_model('proposals', 'Talk')
|
||||||
|
mapping = {
|
||||||
|
0: 'conference (short)',
|
||||||
|
1: 'conference (long)',
|
||||||
|
2: 'workshop',
|
||||||
|
3: 'stand',
|
||||||
|
4: 'other',
|
||||||
|
}
|
||||||
|
for talk in Talk.objects.using(db_alias).all():
|
||||||
|
talk.event = Event.objects.using(db_alias).get(site=talk.site, name=mapping[talk.event_old])
|
||||||
|
talk.save()
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('sites', '0002_alter_domain_unique'),
|
||||||
|
('proposals', '0009_auto_20160822_0921'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
# Creation Event model
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Event',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=64)),
|
||||||
|
('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sites.Site')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='event',
|
||||||
|
unique_together=set([('site', 'name')]),
|
||||||
|
),
|
||||||
|
# Move field event to event_old
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='talk',
|
||||||
|
old_name='event',
|
||||||
|
new_name='event_old',
|
||||||
|
),
|
||||||
|
# Add field event as ForeignKey to Event model (with NULL allowed for now)
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='talk',
|
||||||
|
name='event',
|
||||||
|
field=models.ForeignKey(to='proposals.Event', null=True),
|
||||||
|
),
|
||||||
|
# We slightly need to modify the ordering to work with the M2M
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='talk',
|
||||||
|
options={'ordering': ('event__id',)},
|
||||||
|
),
|
||||||
|
# Migrate the data from event_old field to event field
|
||||||
|
migrations.RunPython(migrate_event),
|
||||||
|
# Remove the event_old field as data have been migrated
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='talk',
|
||||||
|
name='event_old',
|
||||||
|
),
|
||||||
|
# As data are now migrated, switch to null=False for event field
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='talk',
|
||||||
|
name='event',
|
||||||
|
field=models.ForeignKey(to='proposals.Event')
|
||||||
|
),
|
||||||
|
]
|
|
@ -6,6 +6,7 @@ from django.core.urlresolvers import reverse
|
||||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from django.utils.translation import ugettext
|
||||||
|
|
||||||
from autoslug import AutoSlugField
|
from autoslug import AutoSlugField
|
||||||
|
|
||||||
|
@ -44,9 +45,19 @@ class Topic(PonyConfModel):
|
||||||
return reverse('list-talks-by-topic', kwargs={'topic': self.slug})
|
return reverse('list-talks-by-topic', kwargs={'topic': self.slug})
|
||||||
|
|
||||||
|
|
||||||
class Talk(PonyConfModel):
|
class Event(models.Model):
|
||||||
|
|
||||||
EVENTS = IntEnum('Event', 'conference_short conference_long workshop stand other')
|
site = models.ForeignKey(Site, on_delete=models.CASCADE)
|
||||||
|
name = models.CharField(max_length=64)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = ('site', 'name')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return ugettext(self.name)
|
||||||
|
|
||||||
|
|
||||||
|
class Talk(PonyConfModel):
|
||||||
|
|
||||||
site = models.ForeignKey(Site, on_delete=models.CASCADE)
|
site = models.ForeignKey(Site, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
@ -58,7 +69,7 @@ class Talk(PonyConfModel):
|
||||||
description = models.TextField(blank=True, verbose_name=_('Description'))
|
description = models.TextField(blank=True, verbose_name=_('Description'))
|
||||||
topics = models.ManyToManyField(Topic, blank=True, verbose_name=_('Topics'))
|
topics = models.ManyToManyField(Topic, blank=True, verbose_name=_('Topics'))
|
||||||
notes = models.TextField(blank=True, verbose_name=_('Notes'))
|
notes = models.TextField(blank=True, verbose_name=_('Notes'))
|
||||||
event = models.IntegerField(choices=enum_to_choices(EVENTS), default=EVENTS.conference_short.value, verbose_name=_('Format'))
|
event = models.ForeignKey(Event)
|
||||||
accepted = models.NullBooleanField(default=None)
|
accepted = models.NullBooleanField(default=None)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -83,7 +94,7 @@ class Talk(PonyConfModel):
|
||||||
return query_sum(self.vote_set, 'vote')
|
return query_sum(self.vote_set, 'vote')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('event',)
|
ordering = ('event__id',)
|
||||||
|
|
||||||
|
|
||||||
class Vote(PonyConfModel):
|
class Vote(PonyConfModel):
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
from django.db.models.signals import m2m_changed, post_migrate, post_save
|
from django.db.models.signals import m2m_changed, post_save
|
||||||
from django.dispatch import Signal, receiver
|
from django.dispatch import Signal, receiver
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
|
from django.utils.translation import ugettext_noop
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
from accounts.models import Participation
|
from accounts.models import Participation
|
||||||
|
|
||||||
from .models import Conference, Talk, Topic
|
from .models import Conference, Talk, Topic, Event
|
||||||
|
|
||||||
|
|
||||||
talk_added = Signal(providing_args=["sender", "instance", "author"])
|
talk_added = Signal(providing_args=["sender", "instance", "author"])
|
||||||
talk_edited = Signal(providing_args=["sender", "instance", "author"])
|
talk_edited = Signal(providing_args=["sender", "instance", "author"])
|
||||||
|
@ -15,6 +18,24 @@ def create_conference(sender, instance, **kwargs):
|
||||||
Conference.objects.get_or_create(site=instance)
|
Conference.objects.get_or_create(site=instance)
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(post_save, sender=Site, dispatch_uid="Create default events type for Site")
|
||||||
|
def create_events(sender, instance, **kwargs):
|
||||||
|
if not Event.objects.filter(site=instance).exists():
|
||||||
|
Event.objects.bulk_create([
|
||||||
|
Event(site=instance, name=ugettext_noop('conference (short)')),
|
||||||
|
Event(site=instance, name=ugettext_noop('conference (long)')),
|
||||||
|
Event(site=instance, name=ugettext_noop('workshop')),
|
||||||
|
Event(site=instance, name=ugettext_noop('stand')),
|
||||||
|
Event(site=instance, name=ugettext_noop('other')),
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def call_first_site_post_save(apps, **kwargs):
|
||||||
|
site = Site.objects.filter(id=getattr(settings, 'SITE_ID', 1))
|
||||||
|
if site.exists():
|
||||||
|
site.first().save()
|
||||||
|
|
||||||
|
|
||||||
@receiver(m2m_changed, sender=Talk.speakers.through, dispatch_uid="Create Participation for speakers")
|
@receiver(m2m_changed, sender=Talk.speakers.through, dispatch_uid="Create Participation for speakers")
|
||||||
def create_participation_for_speakers(sender, instance, action, reverse, model, pk_set, using, **kwargs):
|
def create_participation_for_speakers(sender, instance, action, reverse, model, pk_set, using, **kwargs):
|
||||||
if action != "pre_add":
|
if action != "pre_add":
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
<h3>{% trans "Format:" %}</h3>
|
<h3>{% trans "Format:" %}</h3>
|
||||||
|
|
||||||
<p>{{ talk.get_event_display }}</p>
|
<p>{{ talk.event }}</p>
|
||||||
|
|
||||||
<h3>{% trans "Abstract:" %}</h3>
|
<h3>{% trans "Abstract:" %}</h3>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user