From 3d9d9a554bd606dae2ddff218bddd2757134e0ed Mon Sep 17 00:00:00 2001 From: Guilhem Saurel Date: Thu, 30 Jun 2016 01:02:00 +0200 Subject: [PATCH] sortedm2m, remove Speech, reset migrations BREAK ALL THE THINGS \o/ --- accounts/migrations/0001_initial.py | 23 +++++++- .../migrations/0002_auto_20160615_0949.py | 41 -------------- .../migrations/0003_auto_20160615_2031.py | 26 --------- ...0004_remove_participation_review_topics.py | 19 ------- .../migrations/0005_participation_sound.py | 20 ------- .../migrations/0006_auto_20160625_1137.py | 41 -------------- .../migrations/0007_participation_orga.py | 20 ------- accounts/migrations/0008_profile_notes.py | 20 ------- accounts/tests.py | 12 ++++ conversations/migrations/0001_initial.py | 15 +++-- .../0002_conversationabouttalk_talk.py | 24 -------- .../migrations/0003_auto_20160615_2031.py | 21 ------- .../migrations/0004_auto_20160625_1137.py | 56 ------------------- ponyconf/settings.py | 1 + proposals/admin.py | 3 +- proposals/forms.py | 2 +- proposals/migrations/0001_initial.py | 39 ++++++------- proposals/migrations/0002_topic_reviewers.py | 21 ------- .../migrations/0003_auto_20160625_1037.py | 20 ------- .../migrations/0004_auto_20160625_1137.py | 53 ------------------ proposals/models.py | 30 +--------- proposals/templates/proposals/talk_edit.html | 9 ++- proposals/tests.py | 29 +++++----- proposals/views.py | 17 +++--- requirements.txt | 5 +- 25 files changed, 100 insertions(+), 467 deletions(-) delete mode 100644 accounts/migrations/0002_auto_20160615_0949.py delete mode 100644 accounts/migrations/0003_auto_20160615_2031.py delete mode 100644 accounts/migrations/0004_remove_participation_review_topics.py delete mode 100644 accounts/migrations/0005_participation_sound.py delete mode 100644 accounts/migrations/0006_auto_20160625_1137.py delete mode 100644 accounts/migrations/0007_participation_orga.py delete mode 100644 accounts/migrations/0008_profile_notes.py delete mode 100644 conversations/migrations/0002_conversationabouttalk_talk.py delete mode 100644 conversations/migrations/0003_auto_20160615_2031.py delete mode 100644 conversations/migrations/0004_auto_20160625_1137.py delete mode 100644 proposals/migrations/0002_topic_reviewers.py delete mode 100644 proposals/migrations/0003_auto_20160625_1037.py delete mode 100644 proposals/migrations/0004_auto_20160625_1137.py diff --git a/accounts/migrations/0001_initial.py b/accounts/migrations/0001_initial.py index b5a8e0f..09cfbba 100644 --- a/accounts/migrations/0001_initial.py +++ b/accounts/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9.7 on 2016-06-15 09:49 +# Generated by Django 1.9.7 on 2016-06-29 22:03 from __future__ import unicode_literals import accounts.utils @@ -16,6 +16,7 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('sites', '0002_alter_domain_unique'), ] operations = [ @@ -23,11 +24,17 @@ class Migration(migrations.Migration): name='Participation', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), ('arrival', models.DateTimeField(blank=True, null=True)), ('departure', models.DateTimeField(blank=True, null=True)), - ('transport', models.IntegerField(blank=True, choices=[(1, 'train'), (2, 'plane')], null=True)), + ('transport', models.IntegerField(blank=True, choices=[(1, 'train'), (2, 'plane'), (3, 'others')], null=True)), ('connector', models.IntegerField(blank=True, choices=[(1, 'VGA'), (2, 'HDMI'), (3, 'miniDP')], null=True)), ('constraints', models.TextField(blank=True)), + ('sound', models.BooleanField(default=False, verbose_name='I need sound')), + ('orga', models.BooleanField(default=False)), + ('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], managers=[ ('objects', django.db.models.manager.Manager()), @@ -38,9 +45,19 @@ class Migration(migrations.Migration): name='Profile', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), ('biography', models.TextField(blank=True, verbose_name='Biography')), - ('email_token', models.CharField(default=accounts.utils.generate_user_uid, max_length=12)), + ('email_token', models.CharField(default=accounts.utils.generate_user_uid, max_length=12, unique=True)), + ('notes', models.TextField(default='')), ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], + options={ + 'abstract': False, + }, + ), + migrations.AlterUniqueTogether( + name='participation', + unique_together=set([('site', 'user')]), ), ] diff --git a/accounts/migrations/0002_auto_20160615_0949.py b/accounts/migrations/0002_auto_20160615_0949.py deleted file mode 100644 index c7a61a2..0000000 --- a/accounts/migrations/0002_auto_20160615_0949.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.7 on 2016-06-15 09:49 -from __future__ import unicode_literals - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('proposals', '0001_initial'), - ('sites', '0002_alter_domain_unique'), - ('accounts', '0001_initial'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.AddField( - model_name='participation', - name='review_topics', - field=models.ManyToManyField(blank=True, to='proposals.Topic'), - ), - migrations.AddField( - model_name='participation', - name='site', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sites.Site'), - ), - migrations.AddField( - model_name='participation', - name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), - ), - migrations.AlterUniqueTogether( - name='participation', - unique_together=set([('site', 'user')]), - ), - ] diff --git a/accounts/migrations/0003_auto_20160615_2031.py b/accounts/migrations/0003_auto_20160615_2031.py deleted file mode 100644 index 412c6e9..0000000 --- a/accounts/migrations/0003_auto_20160615_2031.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.7 on 2016-06-15 20:31 -from __future__ import unicode_literals - -import accounts.utils -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('accounts', '0002_auto_20160615_0949'), - ] - - operations = [ - migrations.AlterField( - model_name='participation', - name='transport', - field=models.IntegerField(blank=True, choices=[(1, 'train'), (2, 'plane'), (3, 'others')], null=True), - ), - migrations.AlterField( - model_name='profile', - name='email_token', - field=models.CharField(default=accounts.utils.generate_user_uid, max_length=12, unique=True), - ), - ] diff --git a/accounts/migrations/0004_remove_participation_review_topics.py b/accounts/migrations/0004_remove_participation_review_topics.py deleted file mode 100644 index a729052..0000000 --- a/accounts/migrations/0004_remove_participation_review_topics.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.7 on 2016-06-19 20:26 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('accounts', '0003_auto_20160615_2031'), - ] - - operations = [ - migrations.RemoveField( - model_name='participation', - name='review_topics', - ), - ] diff --git a/accounts/migrations/0005_participation_sound.py b/accounts/migrations/0005_participation_sound.py deleted file mode 100644 index 9e0bc61..0000000 --- a/accounts/migrations/0005_participation_sound.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.7 on 2016-06-25 10:38 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('accounts', '0004_remove_participation_review_topics'), - ] - - operations = [ - migrations.AddField( - model_name='participation', - name='sound', - field=models.BooleanField(default=False, verbose_name='I need sound'), - ), - ] diff --git a/accounts/migrations/0006_auto_20160625_1137.py b/accounts/migrations/0006_auto_20160625_1137.py deleted file mode 100644 index e65d854..0000000 --- a/accounts/migrations/0006_auto_20160625_1137.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.7 on 2016-06-25 11:37 -from __future__ import unicode_literals - -import datetime -from django.db import migrations, models -from django.utils.timezone import utc - - -class Migration(migrations.Migration): - - dependencies = [ - ('accounts', '0005_participation_sound'), - ] - - operations = [ - migrations.AddField( - model_name='participation', - name='created', - field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2016, 6, 25, 11, 37, 1, 575397, tzinfo=utc)), - preserve_default=False, - ), - migrations.AddField( - model_name='participation', - name='updated', - field=models.DateTimeField(auto_now=True, default=datetime.datetime(2016, 6, 25, 11, 37, 5, 56658, tzinfo=utc)), - preserve_default=False, - ), - migrations.AddField( - model_name='profile', - name='created', - field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2016, 6, 25, 11, 37, 6, 538667, tzinfo=utc)), - preserve_default=False, - ), - migrations.AddField( - model_name='profile', - name='updated', - field=models.DateTimeField(auto_now=True, default=datetime.datetime(2016, 6, 25, 11, 37, 7, 804703, tzinfo=utc)), - preserve_default=False, - ), - ] diff --git a/accounts/migrations/0007_participation_orga.py b/accounts/migrations/0007_participation_orga.py deleted file mode 100644 index 24400b5..0000000 --- a/accounts/migrations/0007_participation_orga.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.7 on 2016-06-25 14:37 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('accounts', '0006_auto_20160625_1137'), - ] - - operations = [ - migrations.AddField( - model_name='participation', - name='orga', - field=models.BooleanField(default=False), - ), - ] diff --git a/accounts/migrations/0008_profile_notes.py b/accounts/migrations/0008_profile_notes.py deleted file mode 100644 index 775e229..0000000 --- a/accounts/migrations/0008_profile_notes.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.7 on 2016-06-25 15:03 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('accounts', '0007_participation_orga'), - ] - - operations = [ - migrations.AddField( - model_name='profile', - name='notes', - field=models.TextField(default=''), - ), - ] diff --git a/accounts/tests.py b/accounts/tests.py index ee49c3d..65a5d5a 100644 --- a/accounts/tests.py +++ b/accounts/tests.py @@ -42,9 +42,21 @@ class AccountTests(TestCase): self.client.logout() def test_participant_views(self): + self.assertEqual(self.client.get(reverse('register')).status_code, 200) self.client.login(username='b', password='b') self.assertEqual(self.client.get(reverse('list-participant')).status_code, 302) b = User.objects.get(username='b') b.is_superuser = True b.save() self.assertEqual(self.client.get(reverse('list-participant')).status_code, 200) + self.assertEqual(self.client.post(reverse('edit-participant', kwargs={'username': 'a'}), + {'biography': 'foo', 'notes': 'bar'}).status_code, 403) + b = Participation.on_site.get(user=b) + b.orga = True + b.save() + self.assertEqual(self.client.post(reverse('edit-participant', kwargs={'username': 'a'}), + {'biography': 'foo', 'nootes': 'bar'}).status_code, 200) + self.assertEqual(User.objects.get(username='a').profile.biography, '') + self.assertEqual(self.client.post(reverse('edit-participant', kwargs={'username': 'a'}), + {'biography': 'foo', 'notes': 'bar'}).status_code, 200) + self.assertEqual(User.objects.get(username='a').profile.biography, 'foo') diff --git a/conversations/migrations/0001_initial.py b/conversations/migrations/0001_initial.py index 59949b7..58749dc 100644 --- a/conversations/migrations/0001_initial.py +++ b/conversations/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9.7 on 2016-06-15 09:49 +# Generated by Django 1.9.7 on 2016-06-29 22:04 from __future__ import unicode_literals import conversations.utils @@ -14,6 +14,7 @@ class Migration(migrations.Migration): dependencies = [ ('accounts', '0001_initial'), + ('proposals', '0001_initial'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('contenttypes', '0002_remove_content_type_name'), ] @@ -23,7 +24,10 @@ class Migration(migrations.Migration): name='ConversationAboutTalk', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), ('subscribers', models.ManyToManyField(blank=True, related_name='_conversationabouttalk_subscribers_+', to=settings.AUTH_USER_MODEL)), + ('talk', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='conversation', to='proposals.Talk')), ], options={ 'abstract': False, @@ -33,6 +37,8 @@ class Migration(migrations.Migration): name='ConversationWithParticipant', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), ('participation', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='conversation', to='accounts.Participation')), ('subscribers', models.ManyToManyField(blank=True, related_name='_conversationwithparticipant_subscribers_+', to=settings.AUTH_USER_MODEL)), ], @@ -44,15 +50,16 @@ class Migration(migrations.Migration): name='Message', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), ('object_id', models.PositiveIntegerField()), - ('token', models.CharField(default=conversations.utils.generate_message_token, max_length=64)), - ('date', models.DateTimeField(auto_now_add=True)), + ('token', models.CharField(default=conversations.utils.generate_message_token, max_length=64, unique=True)), ('content', models.TextField()), ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), ], options={ - 'ordering': ['date'], + 'ordering': ['created'], }, ), ] diff --git a/conversations/migrations/0002_conversationabouttalk_talk.py b/conversations/migrations/0002_conversationabouttalk_talk.py deleted file mode 100644 index c5281fe..0000000 --- a/conversations/migrations/0002_conversationabouttalk_talk.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.7 on 2016-06-15 09:49 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('proposals', '0001_initial'), - ('conversations', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='conversationabouttalk', - name='talk', - field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='conversation', to='proposals.Talk'), - ), - ] diff --git a/conversations/migrations/0003_auto_20160615_2031.py b/conversations/migrations/0003_auto_20160615_2031.py deleted file mode 100644 index 8911e17..0000000 --- a/conversations/migrations/0003_auto_20160615_2031.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.7 on 2016-06-15 20:31 -from __future__ import unicode_literals - -import conversations.utils -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('conversations', '0002_conversationabouttalk_talk'), - ] - - operations = [ - migrations.AlterField( - model_name='message', - name='token', - field=models.CharField(default=conversations.utils.generate_message_token, max_length=64, unique=True), - ), - ] diff --git a/conversations/migrations/0004_auto_20160625_1137.py b/conversations/migrations/0004_auto_20160625_1137.py deleted file mode 100644 index afa7bf5..0000000 --- a/conversations/migrations/0004_auto_20160625_1137.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.7 on 2016-06-25 11:37 -from __future__ import unicode_literals - -import datetime -from django.db import migrations, models -from django.utils.timezone import utc - - -class Migration(migrations.Migration): - - dependencies = [ - ('conversations', '0003_auto_20160615_2031'), - ] - - operations = [ - migrations.AlterModelOptions( - name='message', - options={'ordering': ['created']}, - ), - migrations.RenameField( - model_name='message', - old_name='date', - new_name='created', - ), - migrations.AddField( - model_name='conversationabouttalk', - name='created', - field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2016, 6, 25, 11, 37, 10, 600649, tzinfo=utc)), - preserve_default=False, - ), - migrations.AddField( - model_name='conversationabouttalk', - name='updated', - field=models.DateTimeField(auto_now=True, default=datetime.datetime(2016, 6, 25, 11, 37, 12, 58625, tzinfo=utc)), - preserve_default=False, - ), - migrations.AddField( - model_name='conversationwithparticipant', - name='created', - field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2016, 6, 25, 11, 37, 13, 178710, tzinfo=utc)), - preserve_default=False, - ), - migrations.AddField( - model_name='conversationwithparticipant', - name='updated', - field=models.DateTimeField(auto_now=True, default=datetime.datetime(2016, 6, 25, 11, 37, 14, 346657, tzinfo=utc)), - preserve_default=False, - ), - migrations.AddField( - model_name='message', - name='updated', - field=models.DateTimeField(auto_now=True, default=datetime.datetime(2016, 6, 25, 11, 37, 15, 482594, tzinfo=utc)), - preserve_default=False, - ), - ] diff --git a/ponyconf/settings.py b/ponyconf/settings.py index 173cbd1..4a6e2f0 100644 --- a/ponyconf/settings.py +++ b/ponyconf/settings.py @@ -41,6 +41,7 @@ INSTALLED_APPS = [ 'djangobower', 'bootstrap3', 'registration', + 'sortedm2m', # build-in apps 'django.contrib.admin', diff --git a/proposals/admin.py b/proposals/admin.py index fa94429..e35715d 100644 --- a/proposals/admin.py +++ b/proposals/admin.py @@ -1,7 +1,6 @@ from django.contrib import admin -from proposals.models import Speech, Talk, Topic +from proposals.models import Talk, Topic admin.site.register(Topic) admin.site.register(Talk) -admin.site.register(Speech) diff --git a/proposals/forms.py b/proposals/forms.py index 4d565f4..40c975d 100644 --- a/proposals/forms.py +++ b/proposals/forms.py @@ -6,5 +6,5 @@ from proposals.models import Talk __all__ = ['TalkForm'] -TalkForm = modelform_factory(Talk, fields=['title', 'description', 'topics', 'event'], +TalkForm = modelform_factory(Talk, fields=['title', 'description', 'topics', 'event', 'speakers'], widgets={'topics': CheckboxSelectMultiple()}) diff --git a/proposals/migrations/0001_initial.py b/proposals/migrations/0001_initial.py index 06b3948..801be09 100644 --- a/proposals/migrations/0001_initial.py +++ b/proposals/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9.7 on 2016-06-15 09:49 +# Generated by Django 1.9.7 on 2016-06-29 22:03 from __future__ import unicode_literals import autoslug.fields @@ -8,6 +8,7 @@ import django.contrib.sites.managers from django.db import migrations, models import django.db.models.deletion import django.db.models.manager +import sortedm2m.fields class Migration(migrations.Migration): @@ -15,34 +16,29 @@ class Migration(migrations.Migration): initial = True dependencies = [ + ('accounts', '0001_initial'), ('sites', '0002_alter_domain_unique'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ - migrations.CreateModel( - name='Speech', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('order', models.IntegerField(choices=[(1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5'), (6, '6'), (7, '7')], default=1)), - ('speaker', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - options={ - 'ordering': ['talk', 'order'], - }, - ), migrations.CreateModel( name='Talk', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), ('title', models.CharField(max_length=128, verbose_name='Title')), ('slug', autoslug.fields.AutoSlugField(editable=False, populate_from='title', unique=True)), ('description', models.TextField(blank=True, verbose_name='Description')), - ('event', models.IntegerField(choices=[(1, 'conference'), (2, 'workshop'), (3, 'stand'), (4, 'other')], default=1)), + ('event', models.IntegerField(choices=[(1, 'conference short'), (2, 'conference long'), (3, 'workshop'), (4, 'stand'), (5, 'other')], default=1)), ('proposer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to=settings.AUTH_USER_MODEL)), ('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), - ('speakers', models.ManyToManyField(through='proposals.Speech', to=settings.AUTH_USER_MODEL)), + ('speakers', sortedm2m.fields.SortedManyToManyField(help_text=None, to=settings.AUTH_USER_MODEL)), ], + options={ + 'abstract': False, + }, managers=[ ('objects', django.db.models.manager.Manager()), ('on_site', django.contrib.sites.managers.CurrentSiteManager()), @@ -52,22 +48,19 @@ class Migration(migrations.Migration): name='Topic', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), ('name', models.CharField(max_length=128, unique=True, verbose_name='Name')), ('slug', autoslug.fields.AutoSlugField(editable=False, populate_from='name', unique=True)), + ('reviewers', models.ManyToManyField(blank=True, to='accounts.Participation')), ], + options={ + 'abstract': False, + }, ), migrations.AddField( model_name='talk', name='topics', field=models.ManyToManyField(blank=True, to='proposals.Topic'), ), - migrations.AddField( - model_name='speech', - name='talk', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='proposals.Talk'), - ), - migrations.AlterUniqueTogether( - name='speech', - unique_together=set([('order', 'talk'), ('speaker', 'talk')]), - ), ] diff --git a/proposals/migrations/0002_topic_reviewers.py b/proposals/migrations/0002_topic_reviewers.py deleted file mode 100644 index be206db..0000000 --- a/proposals/migrations/0002_topic_reviewers.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.7 on 2016-06-19 20:26 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('accounts', '0004_remove_participation_review_topics'), - ('proposals', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='topic', - name='reviewers', - field=models.ManyToManyField(blank=True, to='accounts.Participation'), - ), - ] diff --git a/proposals/migrations/0003_auto_20160625_1037.py b/proposals/migrations/0003_auto_20160625_1037.py deleted file mode 100644 index c6ed841..0000000 --- a/proposals/migrations/0003_auto_20160625_1037.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.7 on 2016-06-25 10:37 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('proposals', '0002_topic_reviewers'), - ] - - operations = [ - migrations.AlterField( - model_name='talk', - name='event', - field=models.IntegerField(choices=[(1, 'conference short'), (2, 'conference long'), (3, 'workshop'), (4, 'stand'), (5, 'other')], default=1), - ), - ] diff --git a/proposals/migrations/0004_auto_20160625_1137.py b/proposals/migrations/0004_auto_20160625_1137.py deleted file mode 100644 index 81c0c59..0000000 --- a/proposals/migrations/0004_auto_20160625_1137.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.7 on 2016-06-25 11:37 -from __future__ import unicode_literals - -import datetime -from django.db import migrations, models -from django.utils.timezone import utc - - -class Migration(migrations.Migration): - - dependencies = [ - ('proposals', '0003_auto_20160625_1037'), - ] - - operations = [ - migrations.AddField( - model_name='speech', - name='created', - field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2016, 6, 25, 11, 37, 17, 777177, tzinfo=utc)), - preserve_default=False, - ), - migrations.AddField( - model_name='speech', - name='updated', - field=models.DateTimeField(auto_now=True, default=datetime.datetime(2016, 6, 25, 11, 37, 19, 212622, tzinfo=utc)), - preserve_default=False, - ), - migrations.AddField( - model_name='talk', - name='created', - field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2016, 6, 25, 11, 37, 20, 576319, tzinfo=utc)), - preserve_default=False, - ), - migrations.AddField( - model_name='talk', - name='updated', - field=models.DateTimeField(auto_now=True, default=datetime.datetime(2016, 6, 25, 11, 37, 21, 782675, tzinfo=utc)), - preserve_default=False, - ), - migrations.AddField( - model_name='topic', - name='created', - field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2016, 6, 25, 11, 37, 23, 418591, tzinfo=utc)), - preserve_default=False, - ), - migrations.AddField( - model_name='topic', - name='updated', - field=models.DateTimeField(auto_now=True, default=datetime.datetime(2016, 6, 25, 11, 37, 24, 722598, tzinfo=utc)), - preserve_default=False, - ), - ] diff --git a/proposals/models.py b/proposals/models.py index 9d92cef..df4b006 100644 --- a/proposals/models.py +++ b/proposals/models.py @@ -7,11 +7,12 @@ from django.core.urlresolvers import reverse from django.db import models from autoslug import AutoSlugField +from sortedm2m.fields import SortedManyToManyField from accounts.models import Participation from ponyconf.utils import PonyConfModel, enum_to_choices -__all__ = ['Topic', 'Talk', 'Speech'] +__all__ = ['Topic', 'Talk'] class Topic(PonyConfModel): @@ -35,7 +36,7 @@ class Talk(PonyConfModel): site = models.ForeignKey(Site, on_delete=models.CASCADE) proposer = models.ForeignKey(User, related_name='+') - speakers = models.ManyToManyField(User, through='Speech') + speakers = SortedManyToManyField(User) title = models.CharField(max_length=128, verbose_name='Title') slug = AutoSlugField(populate_from='title', unique=True) description = models.TextField(blank=True, verbose_name='Description') @@ -63,28 +64,3 @@ class Talk(PonyConfModel): except Participation.DoesNotExists: return False return participation.orga or self.topics.filter(reviewers=participation).exists() - - -class Speech(PonyConfModel): - - SPEAKER_NO = tuple((i, str(i)) for i in range(1, 8)) - - speaker = models.ForeignKey(User, on_delete=models.CASCADE) - talk = models.ForeignKey(Talk, on_delete=models.CASCADE) - order = models.IntegerField(choices=SPEAKER_NO, default=1) - - class Meta: - ordering = ['talk', 'order'] - unique_together = ( - ('speaker', 'talk'), - ('order', 'talk'), - ) - - def __str__(self): - return '%s speaking at %s in position %d' % (self.speaker, self.talk, self.order) - - def get_absolute_url(self): - return self.talk.get_absolute_url() - - def username(self): - return self.speaker.username diff --git a/proposals/templates/proposals/talk_edit.html b/proposals/templates/proposals/talk_edit.html index 436e892..b801566 100644 --- a/proposals/templates/proposals/talk_edit.html +++ b/proposals/templates/proposals/talk_edit.html @@ -1,6 +1,6 @@ {% extends 'base.html' %} -{% load bootstrap3 %} +{% load bootstrap3 staticfiles %} {% block talktab %} class="active"{% endblock %} @@ -11,3 +11,10 @@ {% include "_form.html" %} {% endblock %} + +{% block css %}{% endblock %} +{% block js_end %} + + +{% endblock js_end %} + diff --git a/proposals/tests.py b/proposals/tests.py index fd00c1d..e9a2289 100644 --- a/proposals/tests.py +++ b/proposals/tests.py @@ -5,7 +5,7 @@ from django.test import TestCase from accounts.models import Participation -from .models import Speech, Talk, Topic +from .models import Talk, Topic class ProposalsTests(TestCase): @@ -19,19 +19,20 @@ class ProposalsTests(TestCase): def test_everything(self): # talk-edit self.client.login(username='a', password='a') - self.client.post(reverse('add-talk'), {'title': 'super talk', 'description': 'super', 'event': 1, 'topics': 1}) - self.assertEqual(str(Talk.on_site.first()), 'super talk') - self.assertEqual(Talk.on_site.first().description, 'super') + self.client.post(reverse('add-talk'), {'title': 'super talk', 'description': 'super', 'event': 1, 'topics': 1, + 'speakers': 1}) + talk = Talk.on_site.first() + self.assertEqual(str(talk), 'super talk') + self.assertEqual(talk.description, 'super') self.client.post(reverse('edit-talk', kwargs={'talk': 'super-talk'}), - {'title': 'mega talk', 'description': 'mega', 'event': 1}) - self.assertEqual(str(Talk.on_site.first()), 'super talk') # title is read only there - self.assertEqual(Talk.on_site.first().description, 'mega') + {'title': 'mega talk', 'description': 'mega', 'event': 1, 'speakers': 1}) + self.assertEqual(str(talk), 'super talk') # title is read only there + talk = Talk.on_site.first() + self.assertEqual(talk.description, 'mega') # Status Code - self.client.login(username='a', password='a') for view in ['home', 'list-talks', 'add-talk', 'list-topics', 'list-speakers']: self.assertEqual(self.client.get(reverse(view)).status_code, 302 if view == 'list-speakers' else 200) - talk = Talk.on_site.first() self.assertEqual(self.client.get(reverse('edit-talk', kwargs={'talk': talk.slug})).status_code, 200) self.assertEqual(self.client.get(reverse('show-talk', kwargs={'slug': talk.slug})).status_code, 200) self.assertEqual(self.client.get(reverse('list-talks-by-speaker', kwargs={'speaker': 'a'})).status_code, 200) @@ -43,14 +44,16 @@ class ProposalsTests(TestCase): self.assertEqual(self.client.get(reverse('list-talks')).status_code, 200) # Models str & get_asbolute_url - for model in [Talk, Topic, Speech]: + for model in [Talk, Topic]: item = model.objects.first() self.assertEqual(self.client.get(item.get_absolute_url()).status_code, 200) self.assertTrue(str(item)) - self.assertEqual(Speech.objects.first().username(), 'a') - # Talkis_editable_by + # Talk.is_editable_by a, b, c = User.objects.all() self.assertTrue(talk.is_editable_by(c)) - Speech.objects.create(talk=talk, speaker=b, order=2) + self.assertFalse(talk.is_editable_by(b)) + self.client.login(username='a', password='a') + self.client.post(reverse('edit-talk', kwargs={'talk': 'super-talk'}), + {'title': 'mega talk', 'description': 'mega', 'event': 1, 'speakers': "2,1"}) self.assertTrue(talk.is_editable_by(b)) diff --git a/proposals/views.py b/proposals/views.py index ea05bda..4a0f182 100644 --- a/proposals/views.py +++ b/proposals/views.py @@ -9,9 +9,9 @@ from django.views.generic import CreateView, DetailView, ListView from accounts.mixins import StaffRequiredMixin from accounts.models import Participation -from proposals.forms import TalkForm -from proposals.models import Speech, Talk, Topic +from .forms import TalkForm +from .models import Talk, Topic from .signals import new_talk @@ -59,17 +59,16 @@ def talk_edit(request, talk=None): if talk: form.fields['title'].disabled = True form.fields['topics'].disabled = True + else: + form.fields['speakers'].initial = [request.user] if request.method == 'POST' and form.is_valid(): if hasattr(talk, 'id'): talk = form.save() messages.success(request, 'Talk modified successfully!') else: - talk = form.save(commit=False) - talk.site = get_current_site(request) - talk.proposer = request.user - talk.save() - form.save_m2m() - Speech.objects.create(speaker=request.user, talk=talk) + form.instance.site = get_current_site(request) + form.instance.proposer = request.user + talk = form.save() new_talk.send(talk.__class__, instance=talk) messages.success(request, 'Talk proposed successfully!') return redirect(talk.get_absolute_url()) @@ -95,7 +94,7 @@ class TopicCreate(StaffRequiredMixin, CreateView): class SpeakerList(StaffRequiredMixin, ListView): - queryset = User.objects.filter(speech__talk__in=Talk.on_site.all()).distinct() + queryset = User.objects.filter(talk__in=Talk.on_site.all()).distinct() template_name = 'proposals/speaker_list.html' diff --git a/requirements.txt b/requirements.txt index 7cc3e59..9938d34 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,8 @@ django<1.10 -django-bower -django-bootstrap3 django-autoslug +django-bootstrap3 +django-bower django-registration-redux +django-sortedm2m -e git://github.com/Nim65s/django-YummyEmailOrUsernameInsensitiveAuth.git#egg=django-yeouia