From 815602351f36d9f93974d1f523c43d5eca05e873 Mon Sep 17 00:00:00 2001 From: Henrik Levkowetz Date: Mon, 10 Jun 2019 11:32:46 +0000 Subject: [PATCH] This is a series of 50 migrations that changes the Document and DocAlias primary keys from character strings to integers, and makes corresponding code changes. This was prompted by database limitations discovered when trying to make DocAlias use a m2m document field; with 255 long strings as primary keys for Document and DocAlias this violated the MySQL database limitations. Changing the primary keys to integers should also improve efficiency. Due to the data migrations which create the new integer primary keys and adds corresponding integer foreign keys matching the previous string foreign keys in all tables having foreign keys to Document and DocAlias, some of these migrations take a long time. The total set of migrations are expected to have a runtime on the order of 2 hours. - Legacy-Id: 16237 --- .../0003_add_communitylist_docs2_m2m.py | 43 + .../migrations/0004_set_document_m2m_keys.py | 55 + .../migrations/0005_1_del_docs_m2m_table.py | 31 + .../migrations/0005_2_add_docs_m2m_table.py | 33 + .../migrations/0006_copy_docs_m2m_table.py | 56 + .../migrations/0007_remove_docs2_m2m.py | 45 + ietf/community/tests.py | 4 +- ietf/community/utils.py | 2 +- ietf/community/views.py | 8 +- ietf/doc/fields.py | 21 +- .../0013_add_document_docalias_id.py | 25 + .../0014_set_document_docalias_id.py | 35 + .../0015_1_add_fk_to_document_id.py | 121 + .../0015_2_add_doc_document_m2m_fields.py | 93 + .../0016_set_document_docalias_fk.py | 112 + .../0017_make_document_id_primary_key.py | 25 + .../0018_remove_old_document_field.py | 124 + .../migrations/0019_rename_field_document2.py | 83 + .../migrations/0020_copy_docs_m2m_table.py | 33 + ietf/doc/migrations/0021_remove_docs2_m2m.py | 62 + .../0022_document_primary_key_cleanup.py | 67 + ietf/doc/models.py | 8 +- ietf/doc/utils.py | 4 +- ietf/doc/utils_search.py | 8 +- ietf/doc/views_doc.py | 6 +- ietf/doc/views_search.py | 2 +- ietf/group/feeds.py | 2 +- ietf/group/forms.py | 2 +- .../0013_add_groupmilestone_docs2_m2m.py | 52 + .../migrations/0014_set_document_m2m_keys.py | 56 + .../migrations/0015_1_del_docs_m2m_table.py | 40 + .../migrations/0015_2_add_docs_m2m_table.py | 40 + .../migrations/0016_copy_docs_m2m_table.py | 57 + .../group/migrations/0017_remove_docs2_m2m.py | 45 + .../0018_remove_old_document_field.py | 19 + .../migrations/0019_rename_field_document2.py | 21 + ietf/group/tests_review.py | 6 +- ietf/group/views.py | 8 +- ietf/idindex/index.py | 26 +- ietf/iesg/agenda.py | 2 +- ietf/iesg/tests.py | 2 +- ietf/ietfauth/tests.py | 2 +- .../0003_add_ipdocrel_document2_fk.py | 28 + .../0004_remove_iprdocrel_document.py | 19 + .../migrations/0005_rename_field_document2.py | 21 + .../0006_document_primary_key_cleanup.py | 22 + ietf/ipr/tests.py | 18 +- .../migrations/0003_liaison_document2_fk.py | 28 + ...ove_liaisonstatementattachment_document.py | 19 + .../migrations/0005_rename_field_document2.py | 21 + .../0006_document_primary_key_cleanup.py | 22 + .../0015_sessionpresentation_document2_fk.py | 28 + ...016_remove_sessionpresentation_document.py | 33 + .../migrations/0017_rename_field_document2.py | 25 + .../0018_document_primary_key_cleanup.py | 22 + ietf/meeting/models.py | 1 + .../migrations/0002_add_message_docs2_m2m.py | 30 + .../migrations/0003_set_document_m2m_keys.py | 46 + .../migrations/0004_1_del_docs_m2m_table.py | 31 + .../migrations/0004_2_add_docs_m2m_table.py | 31 + .../migrations/0005_copy_docs_m2m_table.py | 27 + .../migrations/0006_remove_docs2_m2m.py | 30 + ietf/name/fixtures/names.json | 2436 ++++++++++++++++- .../migrations/0011_review_document2_fk.py | 58 + .../0012_remove_old_document_field.py | 47 + .../migrations/0013_rename_field_document2.py | 31 + .../0014_document_primary_key_cleanup.py | 27 + ietf/review/models.py | 8 - ietf/review/utils.py | 30 +- ietf/secr/proceedings/proc_utils.py | 8 +- ietf/settings.py | 1 + .../0002_submission_document2_fk.py | 28 + .../0003_remove_old_document_field.py | 19 + .../migrations/0004_rename_field_document2.py | 21 + ietf/submit/tests.py | 12 +- ietf/sync/tests.py | 2 +- .../community/notification_email.txt | 2 +- ietf/templates/doc/document_review.html | 2 +- .../doc/review_assignment_summary.html | 6 +- .../group/manage_review_requests.html | 6 +- ietf/templates/iesg/agenda_doc.txt | 2 +- ietf/templates/ietfauth/review_overview.html | 2 +- ietf/templates/review/reviewer_reminder.txt | 2 +- ietf/templates/review/secretary_reminder.txt | 2 +- ietf/templates/sync/rfceditor_undo.html | 2 +- ietf/utils/history.py | 5 + ietf/utils/test_runner.py | 27 +- ietf/utils/tests.py | 10 - 88 files changed, 4657 insertions(+), 127 deletions(-) create mode 100644 ietf/community/migrations/0003_add_communitylist_docs2_m2m.py create mode 100644 ietf/community/migrations/0004_set_document_m2m_keys.py create mode 100644 ietf/community/migrations/0005_1_del_docs_m2m_table.py create mode 100644 ietf/community/migrations/0005_2_add_docs_m2m_table.py create mode 100644 ietf/community/migrations/0006_copy_docs_m2m_table.py create mode 100644 ietf/community/migrations/0007_remove_docs2_m2m.py create mode 100644 ietf/doc/migrations/0013_add_document_docalias_id.py create mode 100644 ietf/doc/migrations/0014_set_document_docalias_id.py create mode 100644 ietf/doc/migrations/0015_1_add_fk_to_document_id.py create mode 100644 ietf/doc/migrations/0015_2_add_doc_document_m2m_fields.py create mode 100644 ietf/doc/migrations/0016_set_document_docalias_fk.py create mode 100644 ietf/doc/migrations/0017_make_document_id_primary_key.py create mode 100644 ietf/doc/migrations/0018_remove_old_document_field.py create mode 100644 ietf/doc/migrations/0019_rename_field_document2.py create mode 100644 ietf/doc/migrations/0020_copy_docs_m2m_table.py create mode 100644 ietf/doc/migrations/0021_remove_docs2_m2m.py create mode 100644 ietf/doc/migrations/0022_document_primary_key_cleanup.py create mode 100644 ietf/group/migrations/0013_add_groupmilestone_docs2_m2m.py create mode 100644 ietf/group/migrations/0014_set_document_m2m_keys.py create mode 100644 ietf/group/migrations/0015_1_del_docs_m2m_table.py create mode 100644 ietf/group/migrations/0015_2_add_docs_m2m_table.py create mode 100644 ietf/group/migrations/0016_copy_docs_m2m_table.py create mode 100644 ietf/group/migrations/0017_remove_docs2_m2m.py create mode 100644 ietf/group/migrations/0018_remove_old_document_field.py create mode 100644 ietf/group/migrations/0019_rename_field_document2.py create mode 100644 ietf/ipr/migrations/0003_add_ipdocrel_document2_fk.py create mode 100644 ietf/ipr/migrations/0004_remove_iprdocrel_document.py create mode 100644 ietf/ipr/migrations/0005_rename_field_document2.py create mode 100644 ietf/ipr/migrations/0006_document_primary_key_cleanup.py create mode 100644 ietf/liaisons/migrations/0003_liaison_document2_fk.py create mode 100644 ietf/liaisons/migrations/0004_remove_liaisonstatementattachment_document.py create mode 100644 ietf/liaisons/migrations/0005_rename_field_document2.py create mode 100644 ietf/liaisons/migrations/0006_document_primary_key_cleanup.py create mode 100644 ietf/meeting/migrations/0015_sessionpresentation_document2_fk.py create mode 100644 ietf/meeting/migrations/0016_remove_sessionpresentation_document.py create mode 100644 ietf/meeting/migrations/0017_rename_field_document2.py create mode 100644 ietf/meeting/migrations/0018_document_primary_key_cleanup.py create mode 100644 ietf/message/migrations/0002_add_message_docs2_m2m.py create mode 100644 ietf/message/migrations/0003_set_document_m2m_keys.py create mode 100644 ietf/message/migrations/0004_1_del_docs_m2m_table.py create mode 100644 ietf/message/migrations/0004_2_add_docs_m2m_table.py create mode 100644 ietf/message/migrations/0005_copy_docs_m2m_table.py create mode 100644 ietf/message/migrations/0006_remove_docs2_m2m.py create mode 100644 ietf/review/migrations/0011_review_document2_fk.py create mode 100644 ietf/review/migrations/0012_remove_old_document_field.py create mode 100644 ietf/review/migrations/0013_rename_field_document2.py create mode 100644 ietf/review/migrations/0014_document_primary_key_cleanup.py create mode 100644 ietf/submit/migrations/0002_submission_document2_fk.py create mode 100644 ietf/submit/migrations/0003_remove_old_document_field.py create mode 100644 ietf/submit/migrations/0004_rename_field_document2.py diff --git a/ietf/community/migrations/0003_add_communitylist_docs2_m2m.py b/ietf/community/migrations/0003_add_communitylist_docs2_m2m.py new file mode 100644 index 000000000..9b74833eb --- /dev/null +++ b/ietf/community/migrations/0003_add_communitylist_docs2_m2m.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-21 14:23 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('community', '0002_auto_20180220_1052'), + ] + + operations = [ + migrations.CreateModel( + name='CommunityListDocs', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('communitylist', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='community.CommunityList')), + ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id')), + ], + ), + migrations.AddField( + model_name='communitylist', + name='added_docs2', + field=models.ManyToManyField(related_name='communitylists', through='community.CommunityListDocs', to='doc.Document'), + ), + migrations.CreateModel( + name='SearchRuleDocs', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id')), + ('searchrule', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='community.SearchRule')), + ], + ), + migrations.AddField( + model_name='searchrule', + name='name_contains_index2', + field=models.ManyToManyField(related_name='searchrules', through='community.SearchRuleDocs', to='doc.Document'), + ), + ] diff --git a/ietf/community/migrations/0004_set_document_m2m_keys.py b/ietf/community/migrations/0004_set_document_m2m_keys.py new file mode 100644 index 000000000..ab4f81b20 --- /dev/null +++ b/ietf/community/migrations/0004_set_document_m2m_keys.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-21 14:27 +from __future__ import unicode_literals + +import sys + +from tqdm import tqdm + +from django.db import migrations + + +def forward(apps, schema_editor): + + Document = apps.get_model('doc','Document') + CommunityList = apps.get_model('community', 'CommunityList') + CommunityListDocs = apps.get_model('community', 'CommunityListDocs') + SearchRule = apps.get_model('community', 'SearchRule') + SearchRuleDocs = apps.get_model('community', 'SearchRuleDocs') + + # Document id fixup ------------------------------------------------------------ + + objs = Document.objects.in_bulk() + nameid = { o.name: o.id for id, o in objs.iteritems() } + + sys.stderr.write('\n') + + sys.stderr.write(' %s.%s:\n' % (CommunityList.__name__, 'added_docs')) + count = 0 + for l in tqdm(CommunityList.objects.all()): + for d in l.added_docs.all(): + count += 1 + CommunityListDocs.objects.get_or_create(communitylist=l, document_id=nameid[d.name]) + sys.stderr.write(' %s CommunityListDocs objects created\n' % (count, )) + + sys.stderr.write(' %s.%s:\n' % (SearchRule.__name__, 'name_contains_index')) + count = 0 + for r in tqdm(SearchRule.objects.all()): + for d in r.name_contains_index.all(): + count += 1 + SearchRuleDocs.objects.get_or_create(searchrule=r, document_id=nameid[d.name]) + sys.stderr.write(' %s SearchRuleDocs objects created\n' % (count, )) + +def reverse(apps, schema_editor): + pass + +class Migration(migrations.Migration): + + dependencies = [ + ('community', '0003_add_communitylist_docs2_m2m'), + ('doc', '0014_set_document_docalias_id'), + ] + + operations = [ + migrations.RunPython(forward, reverse), + ] diff --git a/ietf/community/migrations/0005_1_del_docs_m2m_table.py b/ietf/community/migrations/0005_1_del_docs_m2m_table.py new file mode 100644 index 000000000..1675631be --- /dev/null +++ b/ietf/community/migrations/0005_1_del_docs_m2m_table.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-22 08:15 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('community', '0004_set_document_m2m_keys'), + ] + + # The implementation of AlterField in Django 1.11 applies + # 'ALTER TABLE MODIFY ...;' in order to fix foregn keys + # to the altered field, but as it seems does _not_ fix up m2m + # intermediary tables in an equivalent manner, so here we remove and + # then recreate the m2m tables so they will have the appropriate field + # types. + + operations = [ + # Remove fields + migrations.RemoveField( + model_name='communitylist', + name='added_docs', + ), + migrations.RemoveField( + model_name='searchrule', + name='name_contains_index', + ), + ] diff --git a/ietf/community/migrations/0005_2_add_docs_m2m_table.py b/ietf/community/migrations/0005_2_add_docs_m2m_table.py new file mode 100644 index 000000000..1d34b2a9b --- /dev/null +++ b/ietf/community/migrations/0005_2_add_docs_m2m_table.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-22 08:15 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('community', '0005_1_del_docs_m2m_table'), + ] + + # The implementation of AlterField in Django 1.11 applies + # 'ALTER TABLE
MODIFY ...;' in order to fix foregn keys + # to the altered field, but as it seems does _not_ fix up m2m + # intermediary tables in an equivalent manner, so here we remove and + # then recreate the m2m tables so they will have the appropriate field + # types. + + operations = [ + # Add fields back (will create the m2m tables with the right field types) + migrations.AddField( + model_name='communitylist', + name='added_docs', + field=models.ManyToManyField(to='doc.Document'), + ), + migrations.AddField( + model_name='searchrule', + name='name_contains_index', + field=models.ManyToManyField(to='doc.Document'), + ), + ] diff --git a/ietf/community/migrations/0006_copy_docs_m2m_table.py b/ietf/community/migrations/0006_copy_docs_m2m_table.py new file mode 100644 index 000000000..9968a7355 --- /dev/null +++ b/ietf/community/migrations/0006_copy_docs_m2m_table.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-27 05:56 +from __future__ import unicode_literals + +from django.db import migrations + +import sys, time + +from tqdm import tqdm + + +def forward(apps, schema_editor): + + CommunityList = apps.get_model('community', 'CommunityList') + CommunityListDocs = apps.get_model('community', 'CommunityListDocs') + SearchRule = apps.get_model('community', 'SearchRule') + SearchRuleDocs = apps.get_model('community', 'SearchRuleDocs') + + # Document id fixup ------------------------------------------------------------ + + + sys.stderr.write('\n') + + sys.stderr.write(' %s.%s:\n' % (CommunityList.__name__, 'added_docs')) + for l in tqdm(CommunityList.objects.all()): + l.added_docs.set([ d.document for d in CommunityListDocs.objects.filter(communitylist=l) ]) + + sys.stderr.write(' %s.%s:\n' % (SearchRule.__name__, 'name_contains_index')) + for r in tqdm(SearchRule.objects.all()): + r.name_contains_index.set([ d.document for d in SearchRuleDocs.objects.filter(searchrule=r) ]) + +def reverse(apps, schema_editor): + pass + +def timestamp(apps, schema_editor): + sys.stderr.write('\n %s' % time.strftime('%Y-%m-%d %H:%M:%S')) + +class Migration(migrations.Migration): + + dependencies = [ + ('community', '0005_2_add_docs_m2m_table'), + ] + + operations = [ + #migrations.RunPython(forward, reverse), + # Alternative: + migrations.RunPython(timestamp, timestamp), + migrations.RunSQL( + "INSERT INTO community_communitylist_added_docs SELECT * FROM community_communitylistdocs;", + ""), + migrations.RunPython(timestamp, timestamp), + migrations.RunSQL( + "INSERT INTO community_searchrule_name_contains_index SELECT * FROM community_searchruledocs;", + ""), + migrations.RunPython(timestamp, timestamp), + ] diff --git a/ietf/community/migrations/0007_remove_docs2_m2m.py b/ietf/community/migrations/0007_remove_docs2_m2m.py new file mode 100644 index 000000000..28364e645 --- /dev/null +++ b/ietf/community/migrations/0007_remove_docs2_m2m.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-30 03:06 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('community', '0006_copy_docs_m2m_table'), + ] + + operations = [ + migrations.RemoveField( + model_name='communitylistdocs', + name='communitylist', + ), + migrations.RemoveField( + model_name='communitylistdocs', + name='document', + ), + migrations.RemoveField( + model_name='searchruledocs', + name='document', + ), + migrations.RemoveField( + model_name='searchruledocs', + name='searchrule', + ), + migrations.RemoveField( + model_name='communitylist', + name='added_docs2', + ), + migrations.RemoveField( + model_name='searchrule', + name='name_contains_index2', + ), + migrations.DeleteModel( + name='CommunityListDocs', + ), + migrations.DeleteModel( + name='SearchRuleDocs', + ), + ] diff --git a/ietf/community/tests.py b/ietf/community/tests.py index 759cce65b..6b8c1bec0 100644 --- a/ietf/community/tests.py +++ b/ietf/community/tests.py @@ -107,7 +107,7 @@ class CommunityListTests(TestCase): self.assertEqual(r.status_code, 200) # add document - r = self.client.post(url, { "action": "add_documents", "documents": draft.pk }) + r = self.client.post(url, { "action": "add_documents", "documents": draft.name }) self.assertEqual(r.status_code, 302) clist = CommunityList.objects.get(user__username="plain") self.assertTrue(clist.added_docs.filter(pk=draft.pk)) @@ -118,7 +118,7 @@ class CommunityListTests(TestCase): self.assertTrue(draft.name in unicontent(r)) # remove document - r = self.client.post(url, { "action": "remove_document", "document": draft.pk }) + r = self.client.post(url, { "action": "remove_document", "document": draft.name }) self.assertEqual(r.status_code, 302) clist = CommunityList.objects.get(user__username="plain") self.assertTrue(not clist.added_docs.filter(pk=draft.pk)) diff --git a/ietf/community/utils.py b/ietf/community/utils.py index de1064645..e4fcd6f35 100644 --- a/ietf/community/utils.py +++ b/ietf/community/utils.py @@ -61,7 +61,7 @@ def augment_docs_with_tracking_info(docs, user): if user and user.is_authenticated: clist = CommunityList.objects.filter(user=user).first() if clist: - tracked.update(docs_tracked_by_community_list(clist).filter(pk__in=docs).values_list("pk", flat=True)) + tracked.update(docs_tracked_by_community_list(clist).filter(pk__in=[ d.pk for d in docs ]).values_list("pk", flat=True)) for d in docs: d.tracked_in_personal_community_list = d.pk in tracked diff --git a/ietf/community/views.py b/ietf/community/views.py index 472665e4e..60eb3de66 100644 --- a/ietf/community/views.py +++ b/ietf/community/views.py @@ -57,9 +57,9 @@ def manage_list(request, username=None, acronym=None, group_type=None): add_doc_form = AddDocumentsForm() if request.method == 'POST' and action == 'remove_document': - document_pk = request.POST.get('document') - if clist.pk is not None and document_pk: - document = get_object_or_404(clist.added_docs, pk=document_pk) + document_name = request.POST.get('document') + if clist.pk is not None and document_name: + document = get_object_or_404(clist.added_docs, name=document_name) clist.added_docs.remove(document) return HttpResponseRedirect("") @@ -209,7 +209,7 @@ def feed(request, username=None, acronym=None, group_type=None): since = datetime.datetime.now() - datetime.timedelta(days=14) events = DocEvent.objects.filter( - doc__in=documents, + doc__id__in=documents, time__gte=since, ).distinct().order_by('-time', '-id').select_related("doc") diff --git a/ietf/doc/fields.py b/ietf/doc/fields.py index 1d19a128e..3285e1416 100644 --- a/ietf/doc/fields.py +++ b/ietf/doc/fields.py @@ -2,6 +2,7 @@ import json from django.utils.html import escape from django import forms +from django.db.models import Q from django.urls import reverse as urlreverse import debug # pyflakes:ignore @@ -52,8 +53,10 @@ class SearchableDocumentsField(forms.CharField): if isinstance(value, (int, long)): value = str(value) if isinstance(value, basestring): - pks = self.parse_select2_value(value) - value = self.model.objects.filter(pk__in=pks) + items = self.parse_select2_value(value) + names = [ i for i in items if not i.isdigit() ] + ids = [ i for i in items if i.isdigit() ] + value = self.model.objects.filter(Q(name__in=names)|Q(id__in=ids)) filter_args = {} if self.model == DocAlias: filter_args["document__type"] = self.doc_type @@ -76,17 +79,17 @@ class SearchableDocumentsField(forms.CharField): def clean(self, value): value = super(SearchableDocumentsField, self).clean(value) - pks = self.parse_select2_value(value) + names = self.parse_select2_value(value) - objs = self.model.objects.filter(pk__in=pks) + objs = self.model.objects.filter(name__in=names) - found_pks = [str(o.pk) for o in objs] - failed_pks = [x for x in pks if x not in found_pks] - if failed_pks: - raise forms.ValidationError(u"Could not recognize the following documents: {pks}. You can only input documents already registered in the Datatracker.".format(pks=", ".join(failed_pks))) + found_names = [str(o.name) for o in objs] + failed_names = [x for x in names if x not in found_names] + if failed_names: + raise forms.ValidationError(u"Could not recognize the following documents: {names}. You can only input documents already registered in the Datatracker.".format(names=", ".join(failed_names))) if self.max_entries != None and len(objs) > self.max_entries: - raise forms.ValidationError(u"You can select at most %s entries only." % self.max_entries) + raise forms.ValidationError(u"You can select at most %s entries." % self.max_entries) return objs diff --git a/ietf/doc/migrations/0013_add_document_docalias_id.py b/ietf/doc/migrations/0013_add_document_docalias_id.py new file mode 100644 index 000000000..23e147f5a --- /dev/null +++ b/ietf/doc/migrations/0013_add_document_docalias_id.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-08 08:41 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0012_add_event_type_closed_review_assignment'), + ] + + operations = [ + migrations.AddField( + model_name='docalias', + name='id', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='document', + name='id', + field=models.IntegerField(default=0), + ), + ] diff --git a/ietf/doc/migrations/0014_set_document_docalias_id.py b/ietf/doc/migrations/0014_set_document_docalias_id.py new file mode 100644 index 000000000..dcade10dd --- /dev/null +++ b/ietf/doc/migrations/0014_set_document_docalias_id.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-08 08:42 +from __future__ import unicode_literals + +import sys + +from tqdm import tqdm + +from django.db import migrations + + +def forward(apps, schema_editor): + Document = apps.get_model('doc','Document') + sys.stderr.write('\n') + for i, d in enumerate(tqdm(Document.objects.all()), start=1): + d.id = i + d.save() + + DocAlias = apps.get_model('doc','DocAlias') + for i, d in enumerate(tqdm(DocAlias.objects.all()), start=1): + d.id = i + d.save() + +def reverse(apps, schema_editor): + pass + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0013_add_document_docalias_id'), + ] + + operations = [ + migrations.RunPython(forward, reverse), + ] diff --git a/ietf/doc/migrations/0015_1_add_fk_to_document_id.py b/ietf/doc/migrations/0015_1_add_fk_to_document_id.py new file mode 100644 index 000000000..023709c4f --- /dev/null +++ b/ietf/doc/migrations/0015_1_add_fk_to_document_id.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-08 10:29 +from __future__ import unicode_literals + +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0014_set_document_docalias_id'), + ] + + operations = [ + # Fix name and id fields first + migrations.AlterField( + model_name='docalias', + name='name', + field=models.CharField(max_length=255, unique=True), + ), + migrations.AlterField( + model_name='docalias', + name='id', + field=models.IntegerField(primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='document', + name='name', + field=models.CharField(max_length=255, unique=True, validators=[django.core.validators.RegexValidator(b'^[-a-z0-9]+$', b'Provide a valid document name consisting of lowercase letters, numbers and hyphens.', b'invalid')]), + ), + migrations.AlterField( + model_name='document', + name='id', + field=models.IntegerField(primary_key=True, serialize=False), + ), + + # Then remaining fields + migrations.AddField( + model_name='docalias', + name='document2', + field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'), + ), + migrations.AddField( + model_name='dochistory', + name='doc2', + field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='history_set', to='doc.Document', to_field=b'id'), + ), + migrations.AddField( + model_name='documentauthor', + name='document2', + field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'), + ), + migrations.AddField( + model_name='documenturl', + name='doc2', + field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'), + ), + migrations.AddField( + model_name='relateddochistory', + name='target2', + field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reversely_related_document_history_set', to='doc.DocAlias', to_field=b'id'), + ), + migrations.AddField( + model_name='relateddocument', + name='source2', + field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'), + ), + migrations.AddField( + model_name='relateddocument', + name='target2', + field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.DocAlias', to_field=b'id'), + ), + migrations.AddField( + model_name='docevent', + name='doc2', + field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='id'), + ), + migrations.AlterField( + model_name='docalias', + name='document', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_docalias', to='doc.Document', to_field=b'name'), + ), + migrations.AlterField( + model_name='dochistory', + name='doc', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_hist', to='doc.Document', to_field=b'name'), + ), + migrations.AlterField( + model_name='documentauthor', + name='document', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_doc_auth', to='doc.Document', to_field=b'name'), + ), + migrations.AlterField( + model_name='documenturl', + name='doc', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_doc_url', to='doc.Document', to_field=b'name'), + ), + migrations.AlterField( + model_name='relateddochistory', + name='target', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_hist_target', to='doc.DocAlias', to_field=b'name'), + ), + migrations.AlterField( + model_name='relateddocument', + name='source', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_rel_source', to='doc.Document', to_field=b'name'), + ), + migrations.AlterField( + model_name='relateddocument', + name='target', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_rel_target', to='doc.DocAlias', to_field=b'name'), + ), + migrations.AlterField( + model_name='docevent', + name='doc', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_docevent', to='doc.Document', to_field=b'name'), + ), + ] diff --git a/ietf/doc/migrations/0015_2_add_doc_document_m2m_fields.py b/ietf/doc/migrations/0015_2_add_doc_document_m2m_fields.py new file mode 100644 index 000000000..10c874892 --- /dev/null +++ b/ietf/doc/migrations/0015_2_add_doc_document_m2m_fields.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-28 12:42 +from __future__ import unicode_literals + +import sys, time + +from django.db import migrations, models +import django.db.models.deletion +import ietf.utils.models + + +def timestamp(apps, schema_editor): + sys.stderr.write('\n %s' % time.strftime('%Y-%m-%d %H:%M:%S')) + +class Migration(migrations.Migration): + + dependencies = [ + ('name', '0006_adjust_statenames'), + ('doc', '0015_1_add_fk_to_document_id'), + ] + + operations = [ + migrations.CreateModel( + name='DocumentLanguages', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='name', related_name='doclanguages')), + ('formallanguagename', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.FormalLanguageName')), + ], + ), + migrations.CreateModel( + name='DocumentStates', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='name', related_name='docstates')), + ('state', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.State')), + ], + ), + migrations.CreateModel( + name='DocumentTags', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='name', related_name='doctags')), + ('doctagname', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.DocTagName')), + ], + ), + migrations.AddField( + model_name='document', + name='formal_languages2', + field=models.ManyToManyField(blank=True, related_name='languagedocs', through='doc.DocumentLanguages', to='name.FormalLanguageName'), + ), + migrations.AddField( + model_name='document', + name='states2', + field=models.ManyToManyField(blank=True, related_name='statedocs', through='doc.DocumentStates', to='doc.State'), + ), + migrations.AddField( + model_name='document', + name='tags2', + field=models.ManyToManyField(blank=True, related_name='tagdocs', through='doc.DocumentTags', to='name.DocTagName'), + ), + # Here we copy the content of the existing implicit m2m tables for + # the Document m2m fields into the explicit through tabeles, in order + # to be able to later set the correct id from name + migrations.RunPython(timestamp, timestamp), + migrations.RunSQL( + "INSERT INTO doc_documentlanguages SELECT * FROM doc_document_formal_languages;", + ""), + migrations.RunPython(timestamp, timestamp), + migrations.RunSQL( + "INSERT INTO doc_documentstates SELECT * FROM doc_document_states;", + ""), + migrations.RunPython(timestamp, timestamp), + migrations.RunSQL( + "INSERT INTO doc_documenttags SELECT * FROM doc_document_tags;", + ""), + migrations.RunPython(timestamp, timestamp), + migrations.AddField( + model_name='documentlanguages', + name='document2', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='id', null=True, default=None), + ), + migrations.AddField( + model_name='documentstates', + name='document2', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='id', null=True, default=None), ), + migrations.AddField( + model_name='documenttags', + name='document2', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='id', null=True, default=None), + + ), + ] diff --git a/ietf/doc/migrations/0016_set_document_docalias_fk.py b/ietf/doc/migrations/0016_set_document_docalias_fk.py new file mode 100644 index 000000000..5bcc9872a --- /dev/null +++ b/ietf/doc/migrations/0016_set_document_docalias_fk.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-08 14:04 +from __future__ import unicode_literals + +import sys + +from tqdm import tqdm + +from django.db import migrations + +def forward(apps, schema_editor): + + def add_id_fk(o, a, nameid): + n = getattr(o, a+'_id') + if n: + i = nameid[n] + if not isinstance(i, (int, long)): + raise ValueError("Inappropriate value: %s: nameid[%s]: %s" % (o.__class__.__name__, n, i)) + if getattr(o, a+'2_id') != i: + setattr(o, a+'2_id', i) + o.save() + + DocAlias = apps.get_model('doc','DocAlias') + DocEvent = apps.get_model('doc', 'DocEvent') + DocHistory = apps.get_model('doc', 'DocHistory') + Document = apps.get_model('doc', 'Document') + DocumentAuthor = apps.get_model('doc', 'DocumentAuthor') + DocumentLanguages = apps.get_model('doc', 'DocumentLanguages') + DocumentStates = apps.get_model('doc', 'DocumentStates') + DocumentTags = apps.get_model('doc', 'DocumentTags') + DocumentURL = apps.get_model('doc', 'DocumentURL') + Group = apps.get_model('group', 'Group') + IprDocRel = apps.get_model('ipr', 'IprDocRel') + LiaisonStatementAttachment = apps.get_model('liaisons', 'LiaisonStatementAttachment') + RelatedDocHistory = apps.get_model('doc', 'RelatedDocHistory') + RelatedDocument = apps.get_model('doc', 'RelatedDocument') + ReviewAssignment = apps.get_model('review', 'ReviewAssignment') + ReviewRequest = apps.get_model('review', 'ReviewRequest') + ReviewWish = apps.get_model('review', 'ReviewWish') + SessionPresentation = apps.get_model('meeting', 'SessionPresentation') + Submission = apps.get_model('submit', 'Submission') + + # Document id fixup ------------------------------------------------------------ + + objs = Document.objects.in_bulk() + nameid = { o.name: o.id for id, o in objs.iteritems() } + + sys.stderr.write('\n') + + sys.stderr.write('Setting Document FKs:\n') + + for C, a in [ + ( DocAlias , 'document'), + ( DocEvent , 'doc'), + ( DocHistory , 'doc'), + ( DocumentAuthor , 'document'), + ( DocumentLanguages , 'document'), + ( DocumentStates , 'document'), + ( DocumentTags , 'document'), + ( DocumentURL , 'doc'), + ( Group , 'charter'), + ( LiaisonStatementAttachment , 'document'), + ( RelatedDocument , 'source'), + ( ReviewAssignment , 'review'), + ( ReviewRequest , 'doc'), + ( ReviewRequest , 'unused_review'), + ( ReviewWish , 'doc'), + ( SessionPresentation , 'document'), + ( Submission , 'draft'), + ]: + sys.stderr.write(' %s.%s:\n' % (C.__name__, a)) + for o in tqdm(C.objects.all()): + add_id_fk(o, a, nameid) + + # DocAlias id fixup ------------------------------------------------------------ + + sys.stderr.write('\n') + + objs = DocAlias.objects.in_bulk() + nameid = { o.name: o.id for id, o in objs.iteritems() } + + sys.stderr.write('Setting DocAlias FKs:\n') + + for C, a in [ + ( IprDocRel , 'document'), + ( RelatedDocument , 'target'), + ( RelatedDocHistory , 'target'), + ]: + sys.stderr.write(' %s.%s:\n' % (C.__name__, a)) + for o in tqdm(C.objects.all()): + add_id_fk(o, a, nameid) + +def reverse(apps, schema_editor): + pass + +class Migration(migrations.Migration): + + dependencies = [ + ('community', '0004_set_document_m2m_keys'), + ('doc', '0015_2_add_doc_document_m2m_fields'), + ('group', '0014_set_document_m2m_keys'), + ('ipr', '0003_add_ipdocrel_document2_fk'), + ('liaisons', '0003_liaison_document2_fk'), + ('meeting', '0015_sessionpresentation_document2_fk'), + ('message', '0003_set_document_m2m_keys'), + ('review', '0011_review_document2_fk'), + ('submit', '0002_submission_document2_fk'), + ] + + operations = [ + migrations.RunPython(forward, reverse), + ] diff --git a/ietf/doc/migrations/0017_make_document_id_primary_key.py b/ietf/doc/migrations/0017_make_document_id_primary_key.py new file mode 100644 index 000000000..48e7cf308 --- /dev/null +++ b/ietf/doc/migrations/0017_make_document_id_primary_key.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-09 05:46 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0016_set_document_docalias_fk'), + ] + + operations = [ + migrations.AlterField( + model_name='docalias', + name='id', + field=models.AutoField(primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='document', + name='id', + field=models.AutoField(primary_key=True, serialize=False), + ), + ] diff --git a/ietf/doc/migrations/0018_remove_old_document_field.py b/ietf/doc/migrations/0018_remove_old_document_field.py new file mode 100644 index 000000000..08401f3cc --- /dev/null +++ b/ietf/doc/migrations/0018_remove_old_document_field.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-20 09:53 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0017_make_document_id_primary_key'), + ] + + operations = [ + migrations.AlterModelOptions( + name='documentauthor', + options={'ordering': ['document2', 'order']}, + ), + migrations.RemoveIndex( + model_name='docevent', + name='doc_doceven_type_43e53e_idx', + ), + migrations.RemoveField( + model_name='docalias', + name='document', + ), + migrations.RemoveField( + model_name='docevent', + name='doc', + ), + migrations.RemoveField( + model_name='dochistory', + name='doc', + ), + migrations.RemoveField( + model_name='documentauthor', + name='document', + ), + migrations.RemoveField( + model_name='documenturl', + name='doc', + ), + migrations.RemoveField( + model_name='relateddochistory', + name='target', + ), + migrations.RemoveField( + model_name='relateddocument', + name='source', + ), + migrations.RemoveField( + model_name='relateddocument', + name='target', + ), + migrations.AddIndex( + model_name='docevent', + index=models.Index(fields=[b'type', b'doc2'], name='doc_doceven_type_ac7748_idx'), + ), + # The following 9 migrations are related to the m2m fields on Document + # Remove the intermediary model field pointing to Document.name + migrations.RemoveField( + model_name='documentlanguages', + name='document', + ), + migrations.RemoveField( + model_name='documentstates', + name='document', + ), + migrations.RemoveField( + model_name='documenttags', + name='document', + ), + # Rename the intermediary model field pointing to Document.id, to + # match the implicit m2m table + migrations.RenameField( + model_name='documentlanguages', + old_name='document2', + new_name='document', + ), + migrations.RenameField( + model_name='documentstates', + old_name='document2', + new_name='document', + ), + migrations.RenameField( + model_name='documenttags', + old_name='document2', + new_name='document', + ), + # Alter the fields to point to Document.pk instead of Document.name + migrations.AlterField( + model_name='documentlanguages', + name='document', + field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), + ), + migrations.AlterField( + model_name='documentstates', + name='document', + field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), + ), + migrations.AlterField( + model_name='documenttags', + name='document', + field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), + ), + # Remove the implicit m2m tables which point to Document.name + migrations.RemoveField( + model_name='document', + name='formal_languages', + ), + migrations.RemoveField( + model_name='document', + name='states', + ), + migrations.RemoveField( + model_name='document', + name='tags', + ), + # Next (in a separate migration, in order to commit the above before + # we proceed) we'll create the implicit m2m tables again, this time + # pointing to Document.id since that's now the primary key. + ] diff --git a/ietf/doc/migrations/0019_rename_field_document2.py b/ietf/doc/migrations/0019_rename_field_document2.py new file mode 100644 index 000000000..4a41ab83e --- /dev/null +++ b/ietf/doc/migrations/0019_rename_field_document2.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-21 05:31 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0018_remove_old_document_field'), + ] + + operations = [ + migrations.AlterModelOptions( + name='documentauthor', + options={'ordering': ['document', 'order']}, + ), + migrations.RemoveIndex( + model_name='docevent', + name='doc_doceven_type_ac7748_idx', + ), + migrations.RenameField( + model_name='docalias', + old_name='document2', + new_name='document', + ), + migrations.RenameField( + model_name='docevent', + old_name='doc2', + new_name='doc', + ), + migrations.RenameField( + model_name='dochistory', + old_name='doc2', + new_name='doc', + ), + migrations.RenameField( + model_name='documentauthor', + old_name='document2', + new_name='document', + ), + migrations.RenameField( + model_name='documenturl', + old_name='doc2', + new_name='doc', + ), + migrations.RenameField( + model_name='relateddochistory', + old_name='target2', + new_name='target', + ), + migrations.RenameField( + model_name='relateddocument', + old_name='source2', + new_name='source', + ), + migrations.RenameField( + model_name='relateddocument', + old_name='target2', + new_name='target', + ), + migrations.AddIndex( + model_name='docevent', + index=models.Index(fields=[b'type', b'doc'], name='doc_doceven_type_43e53e_idx'), + ), + # Add back the m2m field we removed in 0018_... + migrations.AddField( + model_name='document', + name='formal_languages', + field=models.ManyToManyField(blank=True, help_text=b'Formal languages used in document', to='name.FormalLanguageName'), + ), + migrations.AddField( + model_name='document', + name='states', + field=models.ManyToManyField(blank=True, to='doc.State'), + ), + migrations.AddField( + model_name='document', + name='tags', + field=models.ManyToManyField(blank=True, to='name.DocTagName'), + ), + ] diff --git a/ietf/doc/migrations/0020_copy_docs_m2m_table.py b/ietf/doc/migrations/0020_copy_docs_m2m_table.py new file mode 100644 index 000000000..5cfae63bf --- /dev/null +++ b/ietf/doc/migrations/0020_copy_docs_m2m_table.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-21 05:31 +from __future__ import unicode_literals + +import sys, time + +from django.db import migrations + +def timestamp(apps, schema_editor): + sys.stderr.write('\n %s' % time.strftime('%Y-%m-%d %H:%M:%S')) + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0019_rename_field_document2'), + ] + + operations = [ + # Copy the doc IDs from the explicit m2m table to the implicit table + migrations.RunPython(timestamp, timestamp), + migrations.RunSQL( + "INSERT INTO doc_document_formal_languages SELECT id,document_id,formallanguagename_id FROM doc_documentlanguages;", + ""), + migrations.RunPython(timestamp, timestamp), + migrations.RunSQL( + "INSERT INTO doc_document_states SELECT id,document_id,state_id FROM doc_documentstates;", + ""), + migrations.RunPython(timestamp, timestamp), + migrations.RunSQL( + "INSERT INTO doc_document_tags SELECT id,document_id,doctagname_id FROM doc_documenttags;", + ""), + migrations.RunPython(timestamp, timestamp), + ] diff --git a/ietf/doc/migrations/0021_remove_docs2_m2m.py b/ietf/doc/migrations/0021_remove_docs2_m2m.py new file mode 100644 index 000000000..e2bb27c77 --- /dev/null +++ b/ietf/doc/migrations/0021_remove_docs2_m2m.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-30 03:36 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0020_copy_docs_m2m_table'), + ] + + operations = [ + # Get rid of the explicit m2m tables which we needed only to be + # able to convert from Document.name to Document.id + migrations.RemoveField( + model_name='documentlanguages', + name='document', + ), + migrations.RemoveField( + model_name='documentlanguages', + name='formallanguagename', + ), + migrations.RemoveField( + model_name='documentstates', + name='document', + ), + migrations.RemoveField( + model_name='documentstates', + name='state', + ), + migrations.RemoveField( + model_name='documenttags', + name='doctagname', + ), + migrations.RemoveField( + model_name='documenttags', + name='document', + ), + migrations.RemoveField( + model_name='document', + name='formal_languages2', + ), + migrations.RemoveField( + model_name='document', + name='states2', + ), + migrations.RemoveField( + model_name='document', + name='tags2', + ), + migrations.DeleteModel( + name='DocumentLanguages', + ), + migrations.DeleteModel( + name='DocumentStates', + ), + migrations.DeleteModel( + name='DocumentTags', + ), + ] diff --git a/ietf/doc/migrations/0022_document_primary_key_cleanup.py b/ietf/doc/migrations/0022_document_primary_key_cleanup.py new file mode 100644 index 000000000..dba56d2dc --- /dev/null +++ b/ietf/doc/migrations/0022_document_primary_key_cleanup.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-06-10 03:47 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0021_remove_docs2_m2m'), + ] + + operations = [ + migrations.AlterField( + model_name='docalias', + name='document', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), + ), + migrations.AlterField( + model_name='docalias', + name='id', + field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='docevent', + name='doc', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), + ), + migrations.AlterField( + model_name='dochistory', + name='doc', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='history_set', to='doc.Document'), + ), + migrations.AlterField( + model_name='document', + name='id', + field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='documentauthor', + name='document', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), + ), + migrations.AlterField( + model_name='documenturl', + name='doc', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), + ), + migrations.AlterField( + model_name='relateddochistory', + name='target', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reversely_related_document_history_set', to='doc.DocAlias'), + ), + migrations.AlterField( + model_name='relateddocument', + name='source', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), + ), + migrations.AlterField( + model_name='relateddocument', + name='target', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.DocAlias'), + ), + ] diff --git a/ietf/doc/models.py b/ietf/doc/models.py index 0c8509837..87ada27cc 100644 --- a/ietf/doc/models.py +++ b/ietf/doc/models.py @@ -609,7 +609,7 @@ validate_docname = RegexValidator( ) class Document(DocumentInfo): - name = models.CharField(max_length=255, primary_key=True, validators=[validate_docname,]) # immutable + name = models.CharField(max_length=255, validators=[validate_docname,], unique=True) # immutable def __unicode__(self): return self.name @@ -908,8 +908,10 @@ class DocAlias(models.Model): same immutable Document.name, in the tables, but will be referred to by RFC number, primarily, after achieving RFC status. """ - name = models.CharField(max_length=255, primary_key=True) + name = models.CharField(max_length=255, unique=True) document = ForeignKey(Document) +# docs = models.ManyToManyField(Document, related_name='aliases') + def __unicode__(self): return "%s-->%s" % (self.name, self.document.name) document_link = admin_link("document") @@ -1005,7 +1007,7 @@ class DocEvent(models.Model): time = models.DateTimeField(default=datetime.datetime.now, help_text="When the event happened", db_index=True) type = models.CharField(max_length=50, choices=EVENT_TYPES) by = ForeignKey(Person) - doc = ForeignKey('doc.Document') + doc = ForeignKey(Document) rev = models.CharField(verbose_name="revision", max_length=16, null=True, blank=True) desc = models.TextField() diff --git a/ietf/doc/utils.py b/ietf/doc/utils.py index 69fee36f9..c5a05ad1e 100644 --- a/ietf/doc/utils.py +++ b/ietf/doc/utils.py @@ -685,8 +685,8 @@ def extract_complete_replaces_ancestor_mapping_for_docs(names): break relations = RelatedDocument.objects.filter( - source__in=front, relationship="replaces" - ).select_related("target").values_list("source", "target__document") + source__name__in=front, relationship="replaces" + ).select_related("target").values_list("source__name", "target__document__name") if not relations: break diff --git a/ietf/doc/utils_search.py b/ietf/doc/utils_search.py index 31b365e27..d042616d1 100644 --- a/ietf/doc/utils_search.py +++ b/ietf/doc/utils_search.py @@ -20,7 +20,7 @@ def fill_in_telechat_date(docs, doc_dict=None, doc_ids=None): doc_ids = doc_dict.keys() seen = set() - for e in TelechatDocEvent.objects.filter(doc__in=doc_ids, type="scheduled_for_telechat").order_by('-time'): + for e in TelechatDocEvent.objects.filter(doc__id__in=doc_ids, type="scheduled_for_telechat").order_by('-time'): if e.doc_id not in seen: d = doc_dict[e.doc_id] d.telechat_date = wrap_value(d.telechat_date(e)) @@ -49,7 +49,7 @@ def fill_in_document_table_attributes(docs, have_telechat_date=False): doc_dict = dict((d.pk, d) for d in docs) doc_ids = doc_dict.keys() - rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc", document__in=doc_ids).values_list("document", "name")) + rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc", document__id__in=doc_ids).values_list("document__id", "name")) # latest event cache event_types = ("published_rfc", @@ -61,11 +61,11 @@ def fill_in_document_table_attributes(docs, have_telechat_date=False): for e in event_types: d.latest_event_cache[e] = None - for e in DocEvent.objects.filter(doc__in=doc_ids, type__in=event_types).order_by('time'): + for e in DocEvent.objects.filter(doc__id__in=doc_ids, type__in=event_types).order_by('time'): doc_dict[e.doc_id].latest_event_cache[e.type] = e seen = set() - for e in BallotDocEvent.objects.filter(doc__in=doc_ids, type__in=('created_ballot', 'closed_ballot')).order_by('-time','-id'): + for e in BallotDocEvent.objects.filter(doc__id__in=doc_ids, type__in=('created_ballot', 'closed_ballot')).order_by('-time','-id'): if not e.doc_id in seen: doc_dict[e.doc_id].ballot = e if e.type == 'created_ballot' else None seen.add(e.doc_id) diff --git a/ietf/doc/views_doc.py b/ietf/doc/views_doc.py index e9597a506..cd2ee59a9 100644 --- a/ietf/doc/views_doc.py +++ b/ietf/doc/views_doc.py @@ -382,7 +382,7 @@ def document_main(request, name, rev=None): published = doc.latest_event(type="published_rfc") started_iesg_process = doc.latest_event(type="started_iesg_process") - review_assignments = review_assignments_to_list_for_docs([doc]).get(doc.pk, []) + review_assignments = review_assignments_to_list_for_docs([doc]).get(doc.name, []) no_review_from_teams = no_review_from_teams_on_doc(doc, rev or doc.rev) return render(request, "doc/document_draft.html", @@ -598,11 +598,11 @@ def document_main(request, name, rev=None): # If we want to go back to using markup_txt.markup_unicode, call it explicitly here like this: # content = markup_txt.markup_unicode(content, split=False, width=80) - review_assignment = ReviewAssignment.objects.filter(review=doc.name).first() + review_assignment = ReviewAssignment.objects.filter(review__name=doc.name).first() other_reviews = [] if review_assignment: - other_reviews = [r for r in review_assignments_to_list_for_docs([review_assignment.review_request.doc]).get(doc.pk, []) if r != review_assignment] + other_reviews = [r for r in review_assignments_to_list_for_docs([review_assignment.review_request.doc]).get(doc.name, []) if r != review_assignment] return render(request, "doc/document_review.html", dict(doc=doc, diff --git a/ietf/doc/views_search.py b/ietf/doc/views_search.py index 8bd40ed4f..f91a20254 100644 --- a/ietf/doc/views_search.py +++ b/ietf/doc/views_search.py @@ -478,7 +478,7 @@ def index_all_drafts(request): else: heading = "%s Internet-Drafts" % state.name - draft_names = DocAlias.objects.filter(document__states=state).values_list("name", "document") + draft_names = DocAlias.objects.filter(document__states=state).values_list("name", "document__name") names = [] names_to_skip = set() diff --git a/ietf/group/feeds.py b/ietf/group/feeds.py index 3b36b0608..a911bbf81 100644 --- a/ietf/group/feeds.py +++ b/ietf/group/feeds.py @@ -38,7 +38,7 @@ class GroupChangesFeed(Feed): def item_link(self, obj): if isinstance(obj, DocEvent): - return urlreverse("ietf.doc.views_doc.document_main", kwargs={'name': obj.doc_id }) + return urlreverse("ietf.doc.views_doc.document_main", kwargs={'name': obj.doc.name }) elif isinstance(obj, GroupEvent): return obj.group.about_url() diff --git a/ietf/group/forms.py b/ietf/group/forms.py index 635312263..73ee69328 100644 --- a/ietf/group/forms.py +++ b/ietf/group/forms.py @@ -227,7 +227,7 @@ class ManageReviewRequestForm(forms.Form): def __init__(self, review_req, *args, **kwargs): if not "prefix" in kwargs: if review_req.pk is None: - kwargs["prefix"] = "r{}-{}".format(review_req.type_id, review_req.doc_id) + kwargs["prefix"] = "r{}-{}".format(review_req.type_id, review_req.doc.name) else: kwargs["prefix"] = "r{}".format(review_req.pk) diff --git a/ietf/group/migrations/0013_add_groupmilestone_docs2_m2m.py b/ietf/group/migrations/0013_add_groupmilestone_docs2_m2m.py new file mode 100644 index 000000000..2857df1b3 --- /dev/null +++ b/ietf/group/migrations/0013_add_groupmilestone_docs2_m2m.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-02-25 13:02 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import ietf.utils.models + +class Migration(migrations.Migration): + + dependencies = [ + ('group', '0012_add_old_nomcom_announcements'), + ] + + operations = [ + migrations.CreateModel( + name='GroupMilestoneDocs', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id')), + ('groupmilestone', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='group.GroupMilestone')), + ], + ), + migrations.CreateModel( + name='GroupMilestoneHistoryDocs', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id')), + ('groupmilestonehistory', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='group.GroupMilestoneHistory')), + ], + ), + migrations.AddField( + model_name='group', + name='charter2', + field=ietf.utils.models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='chartered_group', to='doc.Document', to_field=b'id'), + ), + migrations.AlterField( + model_name='group', + name='charter', + field=ietf.utils.models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='old_group', to='doc.Document', to_field=b'name'), + ), + migrations.AddField( + model_name='groupmilestone', + name='docs2', + field=models.ManyToManyField(blank=True, related_name='groupmilestones', through='group.GroupMilestoneDocs', to='doc.Document'), + ), + migrations.AddField( + model_name='groupmilestonehistory', + name='docs2', + field=models.ManyToManyField(blank=True, related_name='groupmilestoneshistory', through='group.GroupMilestoneHistoryDocs', to='doc.Document'), + ), + ] diff --git a/ietf/group/migrations/0014_set_document_m2m_keys.py b/ietf/group/migrations/0014_set_document_m2m_keys.py new file mode 100644 index 000000000..73dd5be43 --- /dev/null +++ b/ietf/group/migrations/0014_set_document_m2m_keys.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-10 06:48 +from __future__ import unicode_literals + +import sys + +from tqdm import tqdm + +from django.db import migrations + + +def forward(apps, schema_editor): + + Document = apps.get_model('doc','Document') + GroupMilestone = apps.get_model('group', 'GroupMilestone') + GroupMilestoneDocs = apps.get_model('group', 'GroupMilestoneDocs') + GroupMilestoneHistory = apps.get_model('group', 'GroupMilestoneHistory') + GroupMilestoneHistoryDocs = apps.get_model('group', 'GroupMilestoneHistoryDocs') + + # Document id fixup ------------------------------------------------------------ + + objs = Document.objects.in_bulk() + nameid = { o.name: o.id for id, o in objs.iteritems() } + + sys.stderr.write('\n') + + sys.stderr.write(' %s.%s:\n' % (GroupMilestone.__name__, 'docs')) + count = 0 + for m in tqdm(GroupMilestone.objects.all()): + for d in m.docs.all(): + count += 1 + GroupMilestoneDocs.objects.get_or_create(groupmilestone=m, document_id=nameid[d.name]) + sys.stderr.write(' %s GroupMilestoneDocs objects created\n' % (count, )) + + sys.stderr.write(' %s.%s:\n' % (GroupMilestoneHistory.__name__, 'docs')) + count = 0 + for m in tqdm(GroupMilestoneHistory.objects.all()): + for d in m.docs.all(): + count += 1 + GroupMilestoneHistoryDocs.objects.get_or_create(GroupMilestoneHistory=m, document_id=nameid[d.name]) + sys.stderr.write(' %s GroupMilestoneHistoryDocs objects created\n' % (count, )) + + +def reverse(apps, schema_editor): + pass + +class Migration(migrations.Migration): + + dependencies = [ + ('group', '0013_add_groupmilestone_docs2_m2m'), + ('doc', '0014_set_document_docalias_id'), + ] + + operations = [ + migrations.RunPython(forward, reverse), + ] diff --git a/ietf/group/migrations/0015_1_del_docs_m2m_table.py b/ietf/group/migrations/0015_1_del_docs_m2m_table.py new file mode 100644 index 000000000..b2a570b8b --- /dev/null +++ b/ietf/group/migrations/0015_1_del_docs_m2m_table.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-22 08:00 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('group', '0014_set_document_m2m_keys'), + ] + + # The implementation of AlterField in Django 1.11 applies + # 'ALTER TABLE
MODIFY ...;' in order to fix foregn keys + # to the altered field, but as it seems does _not_ fix up m2m + # intermediary tables in an equivalent manner, so here we remove and + # then recreate the m2m tables so they will have the appropriate field + # types. + + operations = [ + migrations.RemoveField( + model_name='groupmilestone', + name='docs', + ), + migrations.RemoveField( + model_name='groupmilestonehistory', + name='docs', + ), + migrations.AddField( + model_name='groupmilestone', + name='docs', + field=models.ManyToManyField(to='doc.Document'), + ), + migrations.AddField( + model_name='groupmilestonehistory', + name='docs', + field=models.ManyToManyField(to='doc.Document'), + ), + ] diff --git a/ietf/group/migrations/0015_2_add_docs_m2m_table.py b/ietf/group/migrations/0015_2_add_docs_m2m_table.py new file mode 100644 index 000000000..7528014ed --- /dev/null +++ b/ietf/group/migrations/0015_2_add_docs_m2m_table.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-22 08:00 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('group', '0015_1_del_docs_m2m_table'), + ] + + # The implementation of AlterField in Django 1.11 applies + # 'ALTER TABLE
MODIFY ...;' in order to fix foregn keys + # to the altered field, but as it seems does _not_ fix up m2m + # intermediary tables in an equivalent manner, so here we remove and + # then recreate the m2m tables so they will have the appropriate field + # types. + + operations = [ + migrations.RemoveField( + model_name='groupmilestone', + name='docs', + ), + migrations.RemoveField( + model_name='groupmilestonehistory', + name='docs', + ), + migrations.AddField( + model_name='groupmilestone', + name='docs', + field=models.ManyToManyField(blank=True, to='doc.Document'), + ), + migrations.AddField( + model_name='groupmilestonehistory', + name='docs', + field=models.ManyToManyField(blank=True, to='doc.Document'), + ), + ] diff --git a/ietf/group/migrations/0016_copy_docs_m2m_table.py b/ietf/group/migrations/0016_copy_docs_m2m_table.py new file mode 100644 index 000000000..d606fceb0 --- /dev/null +++ b/ietf/group/migrations/0016_copy_docs_m2m_table.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-27 05:57 +from __future__ import unicode_literals + +import sys, time + +from tqdm import tqdm + +from django.db import migrations + + +def forward(apps, schema_editor): + + GroupMilestone = apps.get_model('group', 'GroupMilestone') + GroupMilestoneDocs = apps.get_model('group', 'GroupMilestoneDocs') + GroupMilestoneHistory = apps.get_model('group', 'GroupMilestoneHistory') + GroupMilestoneHistoryDocs = apps.get_model('group', 'GroupMilestoneHistoryDocs') + + # Document id fixup ------------------------------------------------------------ + + sys.stderr.write('\n') + + sys.stderr.write(' %s.%s:\n' % (GroupMilestone.__name__, 'docs')) + for m in tqdm(GroupMilestone.objects.all()): + m.docs.set([ d.document for d in GroupMilestoneDocs.objects.filter(groupmilestone=m) ]) + + sys.stderr.write(' %s.%s:\n' % (GroupMilestoneHistory.__name__, 'docs')) + for m in tqdm(GroupMilestoneHistory.objects.all()): + m.docs.set([ d.document for d in GroupMilestoneHistoryDocs.objects.filter(groupmilestonehistory=m) ]) + + +def reverse(apps, schema_editor): + pass + +def timestamp(apps, schema_editor): + sys.stderr.write('\n %s' % time.strftime('%Y-%m-%d %H:%M:%S')) + +class Migration(migrations.Migration): + + dependencies = [ + ('group', '0015_2_add_docs_m2m_table'), + ] + + operations = [ + #migrations.RunPython(forward, reverse), + migrations.RunPython(timestamp, timestamp), + migrations.RunSQL( + "INSERT INTO group_groupmilestone_docs SELECT * FROM group_groupmilestonedocs;", + "" + ), + migrations.RunPython(timestamp, timestamp), + migrations.RunSQL( + "INSERT INTO group_groupmilestonehistory_docs SELECT * FROM group_groupmilestonehistorydocs;", + "" + ), + migrations.RunPython(timestamp, timestamp), + ] diff --git a/ietf/group/migrations/0017_remove_docs2_m2m.py b/ietf/group/migrations/0017_remove_docs2_m2m.py new file mode 100644 index 000000000..df5d4cf56 --- /dev/null +++ b/ietf/group/migrations/0017_remove_docs2_m2m.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-30 03:23 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('group', '0016_copy_docs_m2m_table'), + ] + + operations = [ + migrations.RemoveField( + model_name='groupmilestonedocs', + name='document', + ), + migrations.RemoveField( + model_name='groupmilestonedocs', + name='groupmilestone', + ), + migrations.RemoveField( + model_name='groupmilestonehistorydocs', + name='document', + ), + migrations.RemoveField( + model_name='groupmilestonehistorydocs', + name='groupmilestonehistory', + ), + migrations.RemoveField( + model_name='groupmilestone', + name='docs2', + ), + migrations.RemoveField( + model_name='groupmilestonehistory', + name='docs2', + ), + migrations.DeleteModel( + name='GroupMilestoneDocs', + ), + migrations.DeleteModel( + name='GroupMilestoneHistoryDocs', + ), + ] diff --git a/ietf/group/migrations/0018_remove_old_document_field.py b/ietf/group/migrations/0018_remove_old_document_field.py new file mode 100644 index 000000000..1b978a215 --- /dev/null +++ b/ietf/group/migrations/0018_remove_old_document_field.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-25 06:51 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('group', '0017_remove_docs2_m2m'), + ] + + operations = [ + migrations.RemoveField( + model_name='group', + name='charter', + ), + ] diff --git a/ietf/group/migrations/0019_rename_field_document2.py b/ietf/group/migrations/0019_rename_field_document2.py new file mode 100644 index 000000000..761d7d7ce --- /dev/null +++ b/ietf/group/migrations/0019_rename_field_document2.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-25 06:52 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0019_rename_field_document2'), + ('group', '0018_remove_old_document_field'), + ] + + operations = [ + migrations.RenameField( + model_name='group', + old_name='charter2', + new_name='charter', + ), + ] diff --git a/ietf/group/tests_review.py b/ietf/group/tests_review.py index 021172a98..e6b781712 100644 --- a/ietf/group/tests_review.py +++ b/ietf/group/tests_review.py @@ -237,7 +237,7 @@ class ReviewTests(TestCase): content = """ {% autoescape off %} Reviewer Deadline Draft - {% for r in review_assignments %}{{ r.reviewer.person.plain_name|ljust:"22" }} {{ r.review_request.deadline|date:"Y-m-d" }} {{ r.review_request.doc_id }}-{% if r.review_request.requested_rev %}{{ r.review_request.requested_rev }}{% else %}{{ r.review_request.doc.rev }}{% endif %} + {% for r in review_assignments %}{{ r.reviewer.person.plain_name|ljust:"22" }} {{ r.review_request.deadline|date:"Y-m-d" }} {{ r.review_request.doc.name }}-{% if r.review_request.requested_rev %}{{ r.review_request.requested_rev }}{% else %}{{ r.review_request.doc.rev }}{% endif %} {% endfor %} {% if rotation_list %}Next in the reviewer rotation: @@ -480,13 +480,13 @@ class ReviewTests(TestCase): empty_outbox() email_reviewer_reminder(review_req) self.assertEqual(len(outbox), 1) - self.assertTrue(review_req.doc_id in outbox[0].get_payload(decode=True).decode("utf-8")) + self.assertTrue(review_req.doc.name in outbox[0].get_payload(decode=True).decode("utf-8")) # email secretary empty_outbox() email_secretary_reminder(review_req, secretary_role) self.assertEqual(len(outbox), 1) - self.assertTrue(review_req.doc_id in outbox[0].get_payload(decode=True).decode("utf-8")) + self.assertTrue(review_req.doc.name in outbox[0].get_payload(decode=True).decode("utf-8")) diff --git a/ietf/group/views.py b/ietf/group/views.py index bdfd95d8a..18c407de4 100644 --- a/ietf/group/views.py +++ b/ietf/group/views.py @@ -1372,7 +1372,7 @@ def reviewer_overview(request, acronym, group_type=None): latest_reqs = [] for d in req_data: if d.state in ["assigned", "accepted"] or len(latest_reqs) < MAX_CLOSED_REQS + open_reqs: - latest_reqs.append((d.assignment_pk, d.doc, d.reviewed_rev, d.assigned_time, d.deadline, + latest_reqs.append((d.assignment_pk, d.doc_name, d.reviewed_rev, d.assigned_time, d.deadline, assignment_state_by_slug.get(d.state), int(math.ceil(d.assignment_to_closure_days)) if d.assignment_to_closure_days is not None else None)) if d.state in ["completed", "completed_in_time", "completed_late"]: @@ -1405,7 +1405,7 @@ def manage_review_requests(request, acronym, group_type=None, assignment_status= document_requests = extract_revision_ordered_review_requests_for_documents_and_replaced( ReviewRequest.objects.filter(state__in=("part-completed", "completed"), team=group).prefetch_related("result"), - set(r.doc_id for r in review_requests), + set(r.doc.name for r in review_requests), ) # we need a mutable query dict for resetting upon saving with @@ -1417,7 +1417,7 @@ def manage_review_requests(request, acronym, group_type=None, assignment_status= # add previous requests l = [] - for r in document_requests.get(req.doc_id, []): + for r in document_requests.get(req.doc.name, []): # take all on the latest reviewed rev if l and l[0].reviewed_rev: if r.doc_id == l[0].doc_id and r.reviewed_rev: @@ -1703,7 +1703,7 @@ def change_reviewer_settings(request, acronym, reviewer_email, group_type=None): msg += "{} is currently assigned to review:".format(reviewer_role.person) for r in review_assignments: msg += "\n\n" - msg += "{} (deadline: {})".format(r.review_request.doc_id, r.review_request.deadline.isoformat()) + msg += "{} (deadline: {})".format(r.review_request.doc.name, r.review_request.deadline.isoformat()) else: msg += "{} does not have any assignments currently.".format(reviewer_role.person) diff --git a/ietf/idindex/index.py b/ietf/idindex/index.py index 2846fc17e..d97f9b544 100644 --- a/ietf/idindex/index.py +++ b/ietf/idindex/index.py @@ -22,17 +22,17 @@ def all_id_txt(): # this returns a lot of data so try to be efficient # precalculations - revision_time = dict(NewRevisionDocEvent.objects.filter(type="new_revision", doc__name__startswith="draft-").order_by('time').values_list("doc_id", "time")) + revision_time = dict(NewRevisionDocEvent.objects.filter(type="new_revision", doc__name__startswith="draft-").order_by('time').values_list("doc__name", "time")) def formatted_rev_date(name): t = revision_time.get(name) return t.strftime("%Y-%m-%d") if t else "" rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc", - document__states=State.objects.get(type="draft", slug="rfc")).values_list("document_id", "name")) + document__states=State.objects.get(type="draft", slug="rfc")).values_list("document__name", "name")) replacements = dict(RelatedDocument.objects.filter(target__document__states=State.objects.get(type="draft", slug="repl"), - relationship="replaces").values_list("target__document_id", "source")) + relationship="replaces").values_list("target__name", "source__name")) # we need a distinct to prevent the queries below from multiplying the result @@ -66,7 +66,7 @@ def all_id_txt(): # handle the rest - not_in_process = all_ids.exclude(pk__in=[d.name for d in in_iesg_process]) + not_in_process = all_ids.exclude(pk__in=[d.pk for d in in_iesg_process]) for s in State.objects.filter(type="draft").order_by("order"): for name, rev in not_in_process.filter(states=s).values_list("name", "rev"): @@ -110,21 +110,21 @@ def all_id2_txt(): drafts = drafts.prefetch_related("states") rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc", - document__states=State.objects.get(type="draft", slug="rfc")).values_list("document_id", "name")) + document__states=State.objects.get(type="draft", slug="rfc")).values_list("document__name", "name")) replacements = dict(RelatedDocument.objects.filter(target__document__states=State.objects.get(type="draft", slug="repl"), - relationship="replaces").values_list("target__document_id", "source")) + relationship="replaces").values_list("target__name", "source__name")) - revision_time = dict(DocEvent.objects.filter(type="new_revision", doc__name__startswith="draft-").order_by('time').values_list("doc_id", "time")) + revision_time = dict(DocEvent.objects.filter(type="new_revision", doc__name__startswith="draft-").order_by('time').values_list("doc__name", "time")) file_types = file_types_for_drafts() authors = {} for a in DocumentAuthor.objects.filter(document__name__startswith="draft-").order_by("order").select_related("email", "person").iterator(): - if a.document_id not in authors: - l = authors[a.document_id] = [] + if a.document.name not in authors: + l = authors[a.document.name] = [] else: - l = authors[a.document_id] + l = authors[a.document.name] if a.email: l.append(u'%s <%s>' % (a.person.plain_name().replace("@", ""), a.email.address.replace(",", ""))) else: @@ -239,8 +239,8 @@ def active_drafts_index_by_group(extra_values=()): docs_dict[d.name]['group_id'] = individual.id # add initial and latest revision time - for time, doc_id in NewRevisionDocEvent.objects.filter(type="new_revision", doc__states=active_state).order_by('-time').values_list("time", "doc_id"): - d = docs_dict.get(doc_id) + for time, doc_name in NewRevisionDocEvent.objects.filter(type="new_revision", doc__states=active_state).order_by('-time').values_list("time", "doc__name"): + d = docs_dict.get(doc_name) if d: if "rev_time" not in d: d["rev_time"] = time @@ -248,7 +248,7 @@ def active_drafts_index_by_group(extra_values=()): # add authors for a in DocumentAuthor.objects.filter(document__states=active_state).order_by("order").select_related("person"): - d = docs_dict.get(a.document_id) + d = docs_dict.get(a.document.name) if d: if "authors" not in d: d["authors"] = [] diff --git a/ietf/iesg/agenda.py b/ietf/iesg/agenda.py index 46a22adf3..78437de81 100644 --- a/ietf/iesg/agenda.py +++ b/ietf/iesg/agenda.py @@ -182,7 +182,7 @@ def fill_in_agenda_docs(date, sections, docs=None): if e and (e.consensus != None): doc.consensus = "Yes" if e.consensus else "No" - doc.review_assignments = review_assignments_for_docs.get(doc.pk, []) + doc.review_assignments = review_assignments_for_docs.get(doc.name, []) elif doc.type_id == "conflrev": doc.conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target.document elif doc.type_id == "charter": diff --git a/ietf/iesg/tests.py b/ietf/iesg/tests.py index 5f80a74ca..16a738512 100644 --- a/ietf/iesg/tests.py +++ b/ietf/iesg/tests.py @@ -493,7 +493,7 @@ class RescheduleOnAgendaTests(TestCase): e.returning_item = True e.save() - form_id = draft.pk + form_id = draft.name url = urlreverse('ietf.iesg.views.agenda_documents') diff --git a/ietf/ietfauth/tests.py b/ietf/ietfauth/tests.py index e1ff2ed50..d8aa71f4c 100644 --- a/ietf/ietfauth/tests.py +++ b/ietf/ietfauth/tests.py @@ -384,7 +384,7 @@ class IetfAuthTests(TestCase): # wish to review r = self.client.post(url, { "action": "add_wish", - 'doc': doc.pk, + 'doc': doc.name, "team": review_req.team_id, }) self.assertEqual(r.status_code, 302) diff --git a/ietf/ipr/migrations/0003_add_ipdocrel_document2_fk.py b/ietf/ipr/migrations/0003_add_ipdocrel_document2_fk.py new file mode 100644 index 000000000..31fd31bcc --- /dev/null +++ b/ietf/ipr/migrations/0003_add_ipdocrel_document2_fk.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-08 11:58 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0015_1_add_fk_to_document_id'), + ('ipr', '0002_auto_20180225_1207'), + ] + + operations = [ + migrations.AddField( + model_name='iprdocrel', + name='document2', + field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.DocAlias', to_field=b'id'), + ), + migrations.AlterField( + model_name='iprdocrel', + name='document', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_ipr', to='doc.DocAlias', to_field=b'name'), + ), + ] diff --git a/ietf/ipr/migrations/0004_remove_iprdocrel_document.py b/ietf/ipr/migrations/0004_remove_iprdocrel_document.py new file mode 100644 index 000000000..e75eb43a1 --- /dev/null +++ b/ietf/ipr/migrations/0004_remove_iprdocrel_document.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-20 09:53 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipr', '0003_add_ipdocrel_document2_fk'), + ] + + operations = [ + migrations.RemoveField( + model_name='iprdocrel', + name='document', + ), + ] diff --git a/ietf/ipr/migrations/0005_rename_field_document2.py b/ietf/ipr/migrations/0005_rename_field_document2.py new file mode 100644 index 000000000..2f793cb21 --- /dev/null +++ b/ietf/ipr/migrations/0005_rename_field_document2.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-21 05:31 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0019_rename_field_document2'), + ('ipr', '0004_remove_iprdocrel_document'), + ] + + operations = [ + migrations.RenameField( + model_name='iprdocrel', + old_name='document2', + new_name='document', + ), + ] diff --git a/ietf/ipr/migrations/0006_document_primary_key_cleanup.py b/ietf/ipr/migrations/0006_document_primary_key_cleanup.py new file mode 100644 index 000000000..a691399f0 --- /dev/null +++ b/ietf/ipr/migrations/0006_document_primary_key_cleanup.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-06-10 03:42 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipr', '0005_rename_field_document2'), + ] + + operations = [ + migrations.AlterField( + model_name='iprdocrel', + name='document', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.DocAlias'), + ), + ] diff --git a/ietf/ipr/tests.py b/ietf/ipr/tests.py index 24a4f3fae..fe03a3c28 100644 --- a/ietf/ipr/tests.py +++ b/ietf/ipr/tests.py @@ -260,9 +260,9 @@ class IprTests(TestCase): "ietfer_contact_info": "555-555-0101", "iprdocrel_set-TOTAL_FORMS": 2, "iprdocrel_set-INITIAL_FORMS": 0, - "iprdocrel_set-0-document": "%s" % draft.docalias_set.first().pk, + "iprdocrel_set-0-document": "%s" % draft.docalias_set.first().name, "iprdocrel_set-0-revisions": '00', - "iprdocrel_set-1-document": DocAlias.objects.filter(name__startswith="rfc").first().pk, + "iprdocrel_set-1-document": DocAlias.objects.filter(name__startswith="rfc").first().name, "patent_number": "SE12345678901", "patent_inventor": "A. Nonymous", "patent_title": "A method of transfering bits", @@ -303,9 +303,9 @@ class IprTests(TestCase): "ietfer_contact_info": "555-555-0101", "iprdocrel_set-TOTAL_FORMS": 2, "iprdocrel_set-INITIAL_FORMS": 0, - "iprdocrel_set-0-document": "%s" % draft.docalias_set.first().pk, + "iprdocrel_set-0-document": "%s" % draft.docalias_set.first().name, "iprdocrel_set-0-revisions": '00', - "iprdocrel_set-1-document": DocAlias.objects.filter(name__startswith="rfc").first().pk, + "iprdocrel_set-1-document": DocAlias.objects.filter(name__startswith="rfc").first().name, "patent_number": "SE12345678901", "patent_inventor": "A. Nonymous", "patent_title": "A method of transfering bits", @@ -351,7 +351,7 @@ class IprTests(TestCase): "holder_legal_name": "Test Legal", "ietfer_contact_info": "555-555-0101", "ietfer_name": "Test Participant", - "iprdocrel_set-0-document": "%s" % draft.docalias_set.first().pk, + "iprdocrel_set-0-document": "%s" % draft.docalias_set.first().name, "iprdocrel_set-0-revisions": '00', "iprdocrel_set-INITIAL_FORMS": 0, "iprdocrel_set-TOTAL_FORMS": 1, @@ -400,9 +400,9 @@ class IprTests(TestCase): "ietfer_contact_info": "555-555-0101", "iprdocrel_set-TOTAL_FORMS": 2, "iprdocrel_set-INITIAL_FORMS": 0, - "iprdocrel_set-0-document": "%s" % draft.docalias_set.first().pk, + "iprdocrel_set-0-document": "%s" % draft.docalias_set.first().name, "iprdocrel_set-0-revisions": '00', - "iprdocrel_set-1-document": DocAlias.objects.filter(name__startswith="rfc").first().pk, + "iprdocrel_set-1-document": DocAlias.objects.filter(name__startswith="rfc").first().name, "patent_number": "SE12345678901", "patent_inventor": "A. Nonymous", "patent_title": "A method of transfering bits", @@ -438,7 +438,7 @@ class IprTests(TestCase): "holder_contact_email": "test@holder.com", "iprdocrel_set-TOTAL_FORMS": 1, "iprdocrel_set-INITIAL_FORMS": 0, - "iprdocrel_set-0-document": "%s" % draft.docalias_set.first().pk, + "iprdocrel_set-0-document": "%s" % draft.docalias_set.first().name, "iprdocrel_set-0-revisions": '00', "patent_number": "SE12345678901", "patent_inventor": "A. Nonymous", @@ -627,7 +627,7 @@ Subject: test 'iprdocrel_set-TOTAL_FORMS' : 1, 'iprdocrel_set-INITIAL_FORMS' : 1, 'iprdocrel_set-0-id': disclosure.pk, - "iprdocrel_set-0-document": disclosure.docs.first().pk, + "iprdocrel_set-0-document": disclosure.docs.first().name, "iprdocrel_set-0-revisions": disclosure.docs.first().document.rev, 'holder_legal_name': disclosure.holder_legal_name, 'patent_number': patent_dict['Number'], diff --git a/ietf/liaisons/migrations/0003_liaison_document2_fk.py b/ietf/liaisons/migrations/0003_liaison_document2_fk.py new file mode 100644 index 000000000..335389423 --- /dev/null +++ b/ietf/liaisons/migrations/0003_liaison_document2_fk.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-08 11:58 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0015_1_add_fk_to_document_id'), + ('liaisons', '0002_auto_20180225_1207'), + ] + + operations = [ + migrations.AddField( + model_name='liaisonstatementattachment', + name='document2', + field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'), + ), + migrations.AlterField( + model_name='liaisonstatementattachment', + name='document', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_liaison', to='doc.Document', to_field=b'name'), + ), + ] diff --git a/ietf/liaisons/migrations/0004_remove_liaisonstatementattachment_document.py b/ietf/liaisons/migrations/0004_remove_liaisonstatementattachment_document.py new file mode 100644 index 000000000..c687f0f00 --- /dev/null +++ b/ietf/liaisons/migrations/0004_remove_liaisonstatementattachment_document.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-20 09:53 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('liaisons', '0003_liaison_document2_fk'), + ] + + operations = [ + migrations.RemoveField( + model_name='liaisonstatementattachment', + name='document', + ), + ] diff --git a/ietf/liaisons/migrations/0005_rename_field_document2.py b/ietf/liaisons/migrations/0005_rename_field_document2.py new file mode 100644 index 000000000..df1f7f2b5 --- /dev/null +++ b/ietf/liaisons/migrations/0005_rename_field_document2.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-21 05:31 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0019_rename_field_document2'), + ('liaisons', '0004_remove_liaisonstatementattachment_document'), + ] + + operations = [ + migrations.RenameField( + model_name='liaisonstatementattachment', + old_name='document2', + new_name='document', + ), + ] diff --git a/ietf/liaisons/migrations/0006_document_primary_key_cleanup.py b/ietf/liaisons/migrations/0006_document_primary_key_cleanup.py new file mode 100644 index 000000000..78bcc13a7 --- /dev/null +++ b/ietf/liaisons/migrations/0006_document_primary_key_cleanup.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-06-10 03:47 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('liaisons', '0005_rename_field_document2'), + ] + + operations = [ + migrations.AlterField( + model_name='liaisonstatementattachment', + name='document', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), + ), + ] diff --git a/ietf/meeting/migrations/0015_sessionpresentation_document2_fk.py b/ietf/meeting/migrations/0015_sessionpresentation_document2_fk.py new file mode 100644 index 000000000..51dca6299 --- /dev/null +++ b/ietf/meeting/migrations/0015_sessionpresentation_document2_fk.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-08 11:58 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0015_1_add_fk_to_document_id'), + ('meeting', '0014_auto_20190426_0305'), + ] + + operations = [ + migrations.AddField( + model_name='sessionpresentation', + name='document2', + field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'), + ), + migrations.AlterField( + model_name='sessionpresentation', + name='document', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_sesspres', to='doc.Document', to_field=b'name'), + ), + ] diff --git a/ietf/meeting/migrations/0016_remove_sessionpresentation_document.py b/ietf/meeting/migrations/0016_remove_sessionpresentation_document.py new file mode 100644 index 000000000..e0d656bc1 --- /dev/null +++ b/ietf/meeting/migrations/0016_remove_sessionpresentation_document.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-21 03:57 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0018_remove_old_document_field'), + ('meeting', '0015_sessionpresentation_document2_fk'), + ] + + operations = [ + + # We need to get rid of the current through table uniqueness + # constraint before we can remove the document column: The table + # has "UNIQUE KEY `session_id` (`session_id`,`document_id`)" + migrations.RunSQL( + "ALTER TABLE `meeting_session_materials` DROP INDEX `session_id`;", + "CREATE UNIQUE INDEX `session_id` ON `meeting_session_materials` (`session_id`, `document_id`);" + ), + ## This doesn't work: + # migrations.RemoveIndex( + # model_name='sessionpresentation', + # name='session_id' + # ), + migrations.RemoveField( + model_name='sessionpresentation', + name='document', + ), + ] diff --git a/ietf/meeting/migrations/0017_rename_field_document2.py b/ietf/meeting/migrations/0017_rename_field_document2.py new file mode 100644 index 000000000..9be7d25ea --- /dev/null +++ b/ietf/meeting/migrations/0017_rename_field_document2.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-21 05:31 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0019_rename_field_document2'), + ('meeting', '0016_remove_sessionpresentation_document'), + ] + + operations = [ + migrations.RenameField( + model_name='sessionpresentation', + old_name='document2', + new_name='document', + ), + migrations.AlterUniqueTogether( + name='sessionpresentation', + unique_together=set([('session', 'document')]), + ), + ] diff --git a/ietf/meeting/migrations/0018_document_primary_key_cleanup.py b/ietf/meeting/migrations/0018_document_primary_key_cleanup.py new file mode 100644 index 000000000..0e5275ed9 --- /dev/null +++ b/ietf/meeting/migrations/0018_document_primary_key_cleanup.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-06-10 03:47 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('meeting', '0017_rename_field_document2'), + ] + + operations = [ + migrations.AlterField( + model_name='sessionpresentation', + name='document', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), + ), + ] diff --git a/ietf/meeting/models.py b/ietf/meeting/models.py index ce8b65b86..ec3d8f39e 100644 --- a/ietf/meeting/models.py +++ b/ietf/meeting/models.py @@ -863,6 +863,7 @@ class SessionPresentation(models.Model): class Meta: db_table = 'meeting_session_materials' ordering = ('order',) + unique_together = (('session', 'document'),) def __unicode__(self): return u"%s -> %s-%s" % (self.session, self.document.name, self.rev) diff --git a/ietf/message/migrations/0002_add_message_docs2_m2m.py b/ietf/message/migrations/0002_add_message_docs2_m2m.py new file mode 100644 index 000000000..f5daf17c4 --- /dev/null +++ b/ietf/message/migrations/0002_add_message_docs2_m2m.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-21 14:23 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('message', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='MessageDocs', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('message', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='message.Message')), + ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id')), + ], + ), + migrations.AddField( + model_name='message', + name='related_docs2', + field=models.ManyToManyField(blank=True, related_name='messages', through='message.MessageDocs', to='doc.Document'), + ), + ] diff --git a/ietf/message/migrations/0003_set_document_m2m_keys.py b/ietf/message/migrations/0003_set_document_m2m_keys.py new file mode 100644 index 000000000..ffdb5adf7 --- /dev/null +++ b/ietf/message/migrations/0003_set_document_m2m_keys.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-21 14:27 +from __future__ import unicode_literals + +import sys + +from tqdm import tqdm + +from django.db import migrations + + +def forward(apps, schema_editor): + + Document = apps.get_model('doc','Document') + Message = apps.get_model('message', 'Message') + MessageDocs = apps.get_model('message', 'MessageDocs') + + + # Document id fixup ------------------------------------------------------------ + + objs = Document.objects.in_bulk() + nameid = { o.name: o.id for id, o in objs.iteritems() } + + sys.stderr.write('\n') + + sys.stderr.write(' %s.%s:\n' % (Message.__name__, 'related_docs')) + count = 0 + for m in tqdm(Message.objects.all()): + for d in m.related_docs.all(): + count += 1; + MessageDocs.objects.get_or_create(message=m, document_id=nameid[d.name]) + sys.stderr.write(' %s MessageDocs objects created\n' % (count, )) + +def reverse(apps, schema_editor): + pass + +class Migration(migrations.Migration): + + dependencies = [ + ('message', '0002_add_message_docs2_m2m'), + ('doc', '0014_set_document_docalias_id'), + ] + + operations = [ + migrations.RunPython(forward, reverse), + ] diff --git a/ietf/message/migrations/0004_1_del_docs_m2m_table.py b/ietf/message/migrations/0004_1_del_docs_m2m_table.py new file mode 100644 index 000000000..6bf2fcc5f --- /dev/null +++ b/ietf/message/migrations/0004_1_del_docs_m2m_table.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-22 08:01 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('message', '0003_set_document_m2m_keys'), + ] + + # The implementation of AlterField in Django 1.11 applies + # 'ALTER TABLE
MODIFY ...;' in order to fix foregn keys + # to the altered field, but as it seems does _not_ fix up m2m + # intermediary tables in an equivalent manner, so here we remove and + # then recreate the m2m tables so they will have the appropriate field + # types. + + operations = [ + migrations.RemoveField( + model_name='message', + name='related_docs', + ), + migrations.AddField( + model_name='message', + name='related_docs', + field=models.ManyToManyField(to='doc.Document'), + ), + ] diff --git a/ietf/message/migrations/0004_2_add_docs_m2m_table.py b/ietf/message/migrations/0004_2_add_docs_m2m_table.py new file mode 100644 index 000000000..314cc5d76 --- /dev/null +++ b/ietf/message/migrations/0004_2_add_docs_m2m_table.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-22 08:01 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('message', '0004_1_del_docs_m2m_table'), + ] + + # The implementation of AlterField in Django 1.11 applies + # 'ALTER TABLE
MODIFY ...;' in order to fix foregn keys + # to the altered field, but as it seems does _not_ fix up m2m + # intermediary tables in an equivalent manner, so here we remove and + # then recreate the m2m tables so they will have the appropriate field + # types. + + operations = [ + migrations.RemoveField( + model_name='message', + name='related_docs', + ), + migrations.AddField( + model_name='message', + name='related_docs', + field=models.ManyToManyField(blank=True, to='doc.Document'), + ), + ] diff --git a/ietf/message/migrations/0005_copy_docs_m2m_table.py b/ietf/message/migrations/0005_copy_docs_m2m_table.py new file mode 100644 index 000000000..ac4afcdf3 --- /dev/null +++ b/ietf/message/migrations/0005_copy_docs_m2m_table.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-27 05:56 +from __future__ import unicode_literals + +import sys, time + +from django.db import migrations + + +def timestamp(apps, schema_editor): + sys.stderr.write('\n %s' % time.strftime('%Y-%m-%d %H:%M:%S')) + +class Migration(migrations.Migration): + + dependencies = [ + ('message', '0004_2_add_docs_m2m_table'), + ] + + operations = [ + #migrations.RunPython(forward, reverse), + migrations.RunPython(timestamp, timestamp), + migrations.RunSQL( + "INSERT INTO message_message_related_docs SELECT * FROM message_messagedocs;", + "" + ), + migrations.RunPython(timestamp, timestamp), + ] diff --git a/ietf/message/migrations/0006_remove_docs2_m2m.py b/ietf/message/migrations/0006_remove_docs2_m2m.py new file mode 100644 index 000000000..48ea5f4e6 --- /dev/null +++ b/ietf/message/migrations/0006_remove_docs2_m2m.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-30 03:32 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('message', '0005_copy_docs_m2m_table'), + ] + + operations = [ + migrations.RemoveField( + model_name='messagedocs', + name='document', + ), + migrations.RemoveField( + model_name='messagedocs', + name='message', + ), + migrations.RemoveField( + model_name='message', + name='related_docs2', + ), + migrations.DeleteModel( + name='MessageDocs', + ), + ] diff --git a/ietf/name/fixtures/names.json b/ietf/name/fixtures/names.json index 8af101227..fde50cdd2 100644 --- a/ietf/name/fixtures/names.json +++ b/ietf/name/fixtures/names.json @@ -2678,13 +2678,13 @@ "fields": { "about_page": "ietf.group.views.group_about", "acts_like_wg": false, - "admin_roles": "[\"chair\"]", + "admin_roles": "[\"chair\",\"advisor\"]", "agenda_type": "side", "create_wiki": true, "custom_group_roles": true, "customize_workflow": false, "default_tab": "ietf.group.views.group_about", - "docman_roles": "[]", + "docman_roles": "[\"chair\"]", "groupman_roles": "[\"chair\",\"advisor\"]", "has_chartering_process": false, "has_default_jabber": false, @@ -10934,11 +10934,2435 @@ "model": "name.topicaudiencename", "pk": "nominees" }, + { + "fields": { + "alias": "AD", + "country": "AD" + }, + "model": "stats.countryalias", + "pk": 1 + }, + { + "fields": { + "alias": "AE", + "country": "AE" + }, + "model": "stats.countryalias", + "pk": 2 + }, + { + "fields": { + "alias": "AF", + "country": "AF" + }, + "model": "stats.countryalias", + "pk": 3 + }, + { + "fields": { + "alias": "AG", + "country": "AG" + }, + "model": "stats.countryalias", + "pk": 4 + }, + { + "fields": { + "alias": "AI", + "country": "AI" + }, + "model": "stats.countryalias", + "pk": 5 + }, + { + "fields": { + "alias": "AL", + "country": "AL" + }, + "model": "stats.countryalias", + "pk": 6 + }, + { + "fields": { + "alias": "AM", + "country": "AM" + }, + "model": "stats.countryalias", + "pk": 7 + }, + { + "fields": { + "alias": "AO", + "country": "AO" + }, + "model": "stats.countryalias", + "pk": 8 + }, + { + "fields": { + "alias": "AQ", + "country": "AQ" + }, + "model": "stats.countryalias", + "pk": 9 + }, + { + "fields": { + "alias": "AR", + "country": "AR" + }, + "model": "stats.countryalias", + "pk": 10 + }, + { + "fields": { + "alias": "AS", + "country": "AS" + }, + "model": "stats.countryalias", + "pk": 11 + }, + { + "fields": { + "alias": "AT", + "country": "AT" + }, + "model": "stats.countryalias", + "pk": 12 + }, + { + "fields": { + "alias": "AU", + "country": "AU" + }, + "model": "stats.countryalias", + "pk": 13 + }, + { + "fields": { + "alias": "AW", + "country": "AW" + }, + "model": "stats.countryalias", + "pk": 14 + }, + { + "fields": { + "alias": "AX", + "country": "AX" + }, + "model": "stats.countryalias", + "pk": 15 + }, + { + "fields": { + "alias": "AZ", + "country": "AZ" + }, + "model": "stats.countryalias", + "pk": 16 + }, + { + "fields": { + "alias": "BA", + "country": "BA" + }, + "model": "stats.countryalias", + "pk": 17 + }, + { + "fields": { + "alias": "BB", + "country": "BB" + }, + "model": "stats.countryalias", + "pk": 18 + }, + { + "fields": { + "alias": "BD", + "country": "BD" + }, + "model": "stats.countryalias", + "pk": 19 + }, + { + "fields": { + "alias": "BE", + "country": "BE" + }, + "model": "stats.countryalias", + "pk": 20 + }, + { + "fields": { + "alias": "BF", + "country": "BF" + }, + "model": "stats.countryalias", + "pk": 21 + }, + { + "fields": { + "alias": "BG", + "country": "BG" + }, + "model": "stats.countryalias", + "pk": 22 + }, + { + "fields": { + "alias": "BH", + "country": "BH" + }, + "model": "stats.countryalias", + "pk": 23 + }, + { + "fields": { + "alias": "BI", + "country": "BI" + }, + "model": "stats.countryalias", + "pk": 24 + }, + { + "fields": { + "alias": "BJ", + "country": "BJ" + }, + "model": "stats.countryalias", + "pk": 25 + }, + { + "fields": { + "alias": "BL", + "country": "BL" + }, + "model": "stats.countryalias", + "pk": 26 + }, + { + "fields": { + "alias": "BM", + "country": "BM" + }, + "model": "stats.countryalias", + "pk": 27 + }, + { + "fields": { + "alias": "BN", + "country": "BN" + }, + "model": "stats.countryalias", + "pk": 28 + }, + { + "fields": { + "alias": "BO", + "country": "BO" + }, + "model": "stats.countryalias", + "pk": 29 + }, + { + "fields": { + "alias": "BQ", + "country": "BQ" + }, + "model": "stats.countryalias", + "pk": 30 + }, + { + "fields": { + "alias": "BR", + "country": "BR" + }, + "model": "stats.countryalias", + "pk": 31 + }, + { + "fields": { + "alias": "BS", + "country": "BS" + }, + "model": "stats.countryalias", + "pk": 32 + }, + { + "fields": { + "alias": "BT", + "country": "BT" + }, + "model": "stats.countryalias", + "pk": 33 + }, + { + "fields": { + "alias": "BV", + "country": "BV" + }, + "model": "stats.countryalias", + "pk": 34 + }, + { + "fields": { + "alias": "BW", + "country": "BW" + }, + "model": "stats.countryalias", + "pk": 35 + }, + { + "fields": { + "alias": "BY", + "country": "BY" + }, + "model": "stats.countryalias", + "pk": 36 + }, + { + "fields": { + "alias": "BZ", + "country": "BZ" + }, + "model": "stats.countryalias", + "pk": 37 + }, + { + "fields": { + "alias": "CA", + "country": "CA" + }, + "model": "stats.countryalias", + "pk": 38 + }, + { + "fields": { + "alias": "CC", + "country": "CC" + }, + "model": "stats.countryalias", + "pk": 39 + }, + { + "fields": { + "alias": "CD", + "country": "CD" + }, + "model": "stats.countryalias", + "pk": 40 + }, + { + "fields": { + "alias": "CF", + "country": "CF" + }, + "model": "stats.countryalias", + "pk": 41 + }, + { + "fields": { + "alias": "CG", + "country": "CG" + }, + "model": "stats.countryalias", + "pk": 42 + }, + { + "fields": { + "alias": "CH", + "country": "CH" + }, + "model": "stats.countryalias", + "pk": 43 + }, + { + "fields": { + "alias": "CI", + "country": "CI" + }, + "model": "stats.countryalias", + "pk": 44 + }, + { + "fields": { + "alias": "CK", + "country": "CK" + }, + "model": "stats.countryalias", + "pk": 45 + }, + { + "fields": { + "alias": "CL", + "country": "CL" + }, + "model": "stats.countryalias", + "pk": 46 + }, + { + "fields": { + "alias": "CM", + "country": "CM" + }, + "model": "stats.countryalias", + "pk": 47 + }, + { + "fields": { + "alias": "CN", + "country": "CN" + }, + "model": "stats.countryalias", + "pk": 48 + }, + { + "fields": { + "alias": "CO", + "country": "CO" + }, + "model": "stats.countryalias", + "pk": 49 + }, + { + "fields": { + "alias": "CR", + "country": "CR" + }, + "model": "stats.countryalias", + "pk": 50 + }, + { + "fields": { + "alias": "CU", + "country": "CU" + }, + "model": "stats.countryalias", + "pk": 51 + }, + { + "fields": { + "alias": "CV", + "country": "CV" + }, + "model": "stats.countryalias", + "pk": 52 + }, + { + "fields": { + "alias": "CW", + "country": "CW" + }, + "model": "stats.countryalias", + "pk": 53 + }, + { + "fields": { + "alias": "CX", + "country": "CX" + }, + "model": "stats.countryalias", + "pk": 54 + }, + { + "fields": { + "alias": "CY", + "country": "CY" + }, + "model": "stats.countryalias", + "pk": 55 + }, + { + "fields": { + "alias": "CZ", + "country": "CZ" + }, + "model": "stats.countryalias", + "pk": 56 + }, + { + "fields": { + "alias": "DE", + "country": "DE" + }, + "model": "stats.countryalias", + "pk": 57 + }, + { + "fields": { + "alias": "DJ", + "country": "DJ" + }, + "model": "stats.countryalias", + "pk": 58 + }, + { + "fields": { + "alias": "DK", + "country": "DK" + }, + "model": "stats.countryalias", + "pk": 59 + }, + { + "fields": { + "alias": "DM", + "country": "DM" + }, + "model": "stats.countryalias", + "pk": 60 + }, + { + "fields": { + "alias": "DO", + "country": "DO" + }, + "model": "stats.countryalias", + "pk": 61 + }, + { + "fields": { + "alias": "DZ", + "country": "DZ" + }, + "model": "stats.countryalias", + "pk": 62 + }, + { + "fields": { + "alias": "EC", + "country": "EC" + }, + "model": "stats.countryalias", + "pk": 63 + }, + { + "fields": { + "alias": "EE", + "country": "EE" + }, + "model": "stats.countryalias", + "pk": 64 + }, + { + "fields": { + "alias": "EG", + "country": "EG" + }, + "model": "stats.countryalias", + "pk": 65 + }, + { + "fields": { + "alias": "EH", + "country": "EH" + }, + "model": "stats.countryalias", + "pk": 66 + }, + { + "fields": { + "alias": "ER", + "country": "ER" + }, + "model": "stats.countryalias", + "pk": 67 + }, + { + "fields": { + "alias": "ES", + "country": "ES" + }, + "model": "stats.countryalias", + "pk": 68 + }, + { + "fields": { + "alias": "ET", + "country": "ET" + }, + "model": "stats.countryalias", + "pk": 69 + }, + { + "fields": { + "alias": "FI", + "country": "FI" + }, + "model": "stats.countryalias", + "pk": 70 + }, + { + "fields": { + "alias": "FJ", + "country": "FJ" + }, + "model": "stats.countryalias", + "pk": 71 + }, + { + "fields": { + "alias": "FK", + "country": "FK" + }, + "model": "stats.countryalias", + "pk": 72 + }, + { + "fields": { + "alias": "FM", + "country": "FM" + }, + "model": "stats.countryalias", + "pk": 73 + }, + { + "fields": { + "alias": "FO", + "country": "FO" + }, + "model": "stats.countryalias", + "pk": 74 + }, + { + "fields": { + "alias": "FR", + "country": "FR" + }, + "model": "stats.countryalias", + "pk": 75 + }, + { + "fields": { + "alias": "GA", + "country": "GA" + }, + "model": "stats.countryalias", + "pk": 76 + }, + { + "fields": { + "alias": "GB", + "country": "GB" + }, + "model": "stats.countryalias", + "pk": 77 + }, + { + "fields": { + "alias": "GD", + "country": "GD" + }, + "model": "stats.countryalias", + "pk": 78 + }, + { + "fields": { + "alias": "GE", + "country": "GE" + }, + "model": "stats.countryalias", + "pk": 79 + }, + { + "fields": { + "alias": "GF", + "country": "GF" + }, + "model": "stats.countryalias", + "pk": 80 + }, + { + "fields": { + "alias": "GG", + "country": "GG" + }, + "model": "stats.countryalias", + "pk": 81 + }, + { + "fields": { + "alias": "GH", + "country": "GH" + }, + "model": "stats.countryalias", + "pk": 82 + }, + { + "fields": { + "alias": "GI", + "country": "GI" + }, + "model": "stats.countryalias", + "pk": 83 + }, + { + "fields": { + "alias": "GL", + "country": "GL" + }, + "model": "stats.countryalias", + "pk": 84 + }, + { + "fields": { + "alias": "GM", + "country": "GM" + }, + "model": "stats.countryalias", + "pk": 85 + }, + { + "fields": { + "alias": "GN", + "country": "GN" + }, + "model": "stats.countryalias", + "pk": 86 + }, + { + "fields": { + "alias": "GP", + "country": "GP" + }, + "model": "stats.countryalias", + "pk": 87 + }, + { + "fields": { + "alias": "GQ", + "country": "GQ" + }, + "model": "stats.countryalias", + "pk": 88 + }, + { + "fields": { + "alias": "GR", + "country": "GR" + }, + "model": "stats.countryalias", + "pk": 89 + }, + { + "fields": { + "alias": "GS", + "country": "GS" + }, + "model": "stats.countryalias", + "pk": 90 + }, + { + "fields": { + "alias": "GT", + "country": "GT" + }, + "model": "stats.countryalias", + "pk": 91 + }, + { + "fields": { + "alias": "GU", + "country": "GU" + }, + "model": "stats.countryalias", + "pk": 92 + }, + { + "fields": { + "alias": "GW", + "country": "GW" + }, + "model": "stats.countryalias", + "pk": 93 + }, + { + "fields": { + "alias": "GY", + "country": "GY" + }, + "model": "stats.countryalias", + "pk": 94 + }, + { + "fields": { + "alias": "HK", + "country": "HK" + }, + "model": "stats.countryalias", + "pk": 95 + }, + { + "fields": { + "alias": "HM", + "country": "HM" + }, + "model": "stats.countryalias", + "pk": 96 + }, + { + "fields": { + "alias": "HN", + "country": "HN" + }, + "model": "stats.countryalias", + "pk": 97 + }, + { + "fields": { + "alias": "HR", + "country": "HR" + }, + "model": "stats.countryalias", + "pk": 98 + }, + { + "fields": { + "alias": "HT", + "country": "HT" + }, + "model": "stats.countryalias", + "pk": 99 + }, + { + "fields": { + "alias": "HU", + "country": "HU" + }, + "model": "stats.countryalias", + "pk": 100 + }, + { + "fields": { + "alias": "ID", + "country": "ID" + }, + "model": "stats.countryalias", + "pk": 101 + }, + { + "fields": { + "alias": "IE", + "country": "IE" + }, + "model": "stats.countryalias", + "pk": 102 + }, + { + "fields": { + "alias": "IL", + "country": "IL" + }, + "model": "stats.countryalias", + "pk": 103 + }, + { + "fields": { + "alias": "IM", + "country": "IM" + }, + "model": "stats.countryalias", + "pk": 104 + }, + { + "fields": { + "alias": "IN", + "country": "IN" + }, + "model": "stats.countryalias", + "pk": 105 + }, + { + "fields": { + "alias": "IO", + "country": "IO" + }, + "model": "stats.countryalias", + "pk": 106 + }, + { + "fields": { + "alias": "IQ", + "country": "IQ" + }, + "model": "stats.countryalias", + "pk": 107 + }, + { + "fields": { + "alias": "IR", + "country": "IR" + }, + "model": "stats.countryalias", + "pk": 108 + }, + { + "fields": { + "alias": "IS", + "country": "IS" + }, + "model": "stats.countryalias", + "pk": 109 + }, + { + "fields": { + "alias": "IT", + "country": "IT" + }, + "model": "stats.countryalias", + "pk": 110 + }, + { + "fields": { + "alias": "JE", + "country": "JE" + }, + "model": "stats.countryalias", + "pk": 111 + }, + { + "fields": { + "alias": "JM", + "country": "JM" + }, + "model": "stats.countryalias", + "pk": 112 + }, + { + "fields": { + "alias": "JO", + "country": "JO" + }, + "model": "stats.countryalias", + "pk": 113 + }, + { + "fields": { + "alias": "JP", + "country": "JP" + }, + "model": "stats.countryalias", + "pk": 114 + }, + { + "fields": { + "alias": "KE", + "country": "KE" + }, + "model": "stats.countryalias", + "pk": 115 + }, + { + "fields": { + "alias": "KG", + "country": "KG" + }, + "model": "stats.countryalias", + "pk": 116 + }, + { + "fields": { + "alias": "KH", + "country": "KH" + }, + "model": "stats.countryalias", + "pk": 117 + }, + { + "fields": { + "alias": "KI", + "country": "KI" + }, + "model": "stats.countryalias", + "pk": 118 + }, + { + "fields": { + "alias": "KM", + "country": "KM" + }, + "model": "stats.countryalias", + "pk": 119 + }, + { + "fields": { + "alias": "KN", + "country": "KN" + }, + "model": "stats.countryalias", + "pk": 120 + }, + { + "fields": { + "alias": "KP", + "country": "KP" + }, + "model": "stats.countryalias", + "pk": 121 + }, + { + "fields": { + "alias": "KR", + "country": "KR" + }, + "model": "stats.countryalias", + "pk": 122 + }, + { + "fields": { + "alias": "KW", + "country": "KW" + }, + "model": "stats.countryalias", + "pk": 123 + }, + { + "fields": { + "alias": "KY", + "country": "KY" + }, + "model": "stats.countryalias", + "pk": 124 + }, + { + "fields": { + "alias": "KZ", + "country": "KZ" + }, + "model": "stats.countryalias", + "pk": 125 + }, + { + "fields": { + "alias": "LA", + "country": "LA" + }, + "model": "stats.countryalias", + "pk": 126 + }, + { + "fields": { + "alias": "LB", + "country": "LB" + }, + "model": "stats.countryalias", + "pk": 127 + }, + { + "fields": { + "alias": "LC", + "country": "LC" + }, + "model": "stats.countryalias", + "pk": 128 + }, + { + "fields": { + "alias": "LI", + "country": "LI" + }, + "model": "stats.countryalias", + "pk": 129 + }, + { + "fields": { + "alias": "LK", + "country": "LK" + }, + "model": "stats.countryalias", + "pk": 130 + }, + { + "fields": { + "alias": "LR", + "country": "LR" + }, + "model": "stats.countryalias", + "pk": 131 + }, + { + "fields": { + "alias": "LS", + "country": "LS" + }, + "model": "stats.countryalias", + "pk": 132 + }, + { + "fields": { + "alias": "LT", + "country": "LT" + }, + "model": "stats.countryalias", + "pk": 133 + }, + { + "fields": { + "alias": "LU", + "country": "LU" + }, + "model": "stats.countryalias", + "pk": 134 + }, + { + "fields": { + "alias": "LV", + "country": "LV" + }, + "model": "stats.countryalias", + "pk": 135 + }, + { + "fields": { + "alias": "LY", + "country": "LY" + }, + "model": "stats.countryalias", + "pk": 136 + }, + { + "fields": { + "alias": "MA", + "country": "MA" + }, + "model": "stats.countryalias", + "pk": 137 + }, + { + "fields": { + "alias": "MC", + "country": "MC" + }, + "model": "stats.countryalias", + "pk": 138 + }, + { + "fields": { + "alias": "MD", + "country": "MD" + }, + "model": "stats.countryalias", + "pk": 139 + }, + { + "fields": { + "alias": "ME", + "country": "ME" + }, + "model": "stats.countryalias", + "pk": 140 + }, + { + "fields": { + "alias": "MF", + "country": "MF" + }, + "model": "stats.countryalias", + "pk": 141 + }, + { + "fields": { + "alias": "MG", + "country": "MG" + }, + "model": "stats.countryalias", + "pk": 142 + }, + { + "fields": { + "alias": "MH", + "country": "MH" + }, + "model": "stats.countryalias", + "pk": 143 + }, + { + "fields": { + "alias": "MK", + "country": "MK" + }, + "model": "stats.countryalias", + "pk": 144 + }, + { + "fields": { + "alias": "ML", + "country": "ML" + }, + "model": "stats.countryalias", + "pk": 145 + }, + { + "fields": { + "alias": "MM", + "country": "MM" + }, + "model": "stats.countryalias", + "pk": 146 + }, + { + "fields": { + "alias": "MN", + "country": "MN" + }, + "model": "stats.countryalias", + "pk": 147 + }, + { + "fields": { + "alias": "MO", + "country": "MO" + }, + "model": "stats.countryalias", + "pk": 148 + }, + { + "fields": { + "alias": "MP", + "country": "MP" + }, + "model": "stats.countryalias", + "pk": 149 + }, + { + "fields": { + "alias": "MQ", + "country": "MQ" + }, + "model": "stats.countryalias", + "pk": 150 + }, + { + "fields": { + "alias": "MR", + "country": "MR" + }, + "model": "stats.countryalias", + "pk": 151 + }, + { + "fields": { + "alias": "MS", + "country": "MS" + }, + "model": "stats.countryalias", + "pk": 152 + }, + { + "fields": { + "alias": "MT", + "country": "MT" + }, + "model": "stats.countryalias", + "pk": 153 + }, + { + "fields": { + "alias": "MU", + "country": "MU" + }, + "model": "stats.countryalias", + "pk": 154 + }, + { + "fields": { + "alias": "MV", + "country": "MV" + }, + "model": "stats.countryalias", + "pk": 155 + }, + { + "fields": { + "alias": "MW", + "country": "MW" + }, + "model": "stats.countryalias", + "pk": 156 + }, + { + "fields": { + "alias": "MX", + "country": "MX" + }, + "model": "stats.countryalias", + "pk": 157 + }, + { + "fields": { + "alias": "MY", + "country": "MY" + }, + "model": "stats.countryalias", + "pk": 158 + }, + { + "fields": { + "alias": "MZ", + "country": "MZ" + }, + "model": "stats.countryalias", + "pk": 159 + }, + { + "fields": { + "alias": "NA", + "country": "NA" + }, + "model": "stats.countryalias", + "pk": 160 + }, + { + "fields": { + "alias": "NC", + "country": "NC" + }, + "model": "stats.countryalias", + "pk": 161 + }, + { + "fields": { + "alias": "NE", + "country": "NE" + }, + "model": "stats.countryalias", + "pk": 162 + }, + { + "fields": { + "alias": "NF", + "country": "NF" + }, + "model": "stats.countryalias", + "pk": 163 + }, + { + "fields": { + "alias": "NG", + "country": "NG" + }, + "model": "stats.countryalias", + "pk": 164 + }, + { + "fields": { + "alias": "NI", + "country": "NI" + }, + "model": "stats.countryalias", + "pk": 165 + }, + { + "fields": { + "alias": "NL", + "country": "NL" + }, + "model": "stats.countryalias", + "pk": 166 + }, + { + "fields": { + "alias": "NO", + "country": "NO" + }, + "model": "stats.countryalias", + "pk": 167 + }, + { + "fields": { + "alias": "NP", + "country": "NP" + }, + "model": "stats.countryalias", + "pk": 168 + }, + { + "fields": { + "alias": "NR", + "country": "NR" + }, + "model": "stats.countryalias", + "pk": 169 + }, + { + "fields": { + "alias": "NU", + "country": "NU" + }, + "model": "stats.countryalias", + "pk": 170 + }, + { + "fields": { + "alias": "NZ", + "country": "NZ" + }, + "model": "stats.countryalias", + "pk": 171 + }, + { + "fields": { + "alias": "OM", + "country": "OM" + }, + "model": "stats.countryalias", + "pk": 172 + }, + { + "fields": { + "alias": "PA", + "country": "PA" + }, + "model": "stats.countryalias", + "pk": 173 + }, + { + "fields": { + "alias": "PE", + "country": "PE" + }, + "model": "stats.countryalias", + "pk": 174 + }, + { + "fields": { + "alias": "PF", + "country": "PF" + }, + "model": "stats.countryalias", + "pk": 175 + }, + { + "fields": { + "alias": "PG", + "country": "PG" + }, + "model": "stats.countryalias", + "pk": 176 + }, + { + "fields": { + "alias": "PH", + "country": "PH" + }, + "model": "stats.countryalias", + "pk": 177 + }, + { + "fields": { + "alias": "PK", + "country": "PK" + }, + "model": "stats.countryalias", + "pk": 178 + }, + { + "fields": { + "alias": "PL", + "country": "PL" + }, + "model": "stats.countryalias", + "pk": 179 + }, + { + "fields": { + "alias": "PM", + "country": "PM" + }, + "model": "stats.countryalias", + "pk": 180 + }, + { + "fields": { + "alias": "PN", + "country": "PN" + }, + "model": "stats.countryalias", + "pk": 181 + }, + { + "fields": { + "alias": "PR", + "country": "PR" + }, + "model": "stats.countryalias", + "pk": 182 + }, + { + "fields": { + "alias": "PS", + "country": "PS" + }, + "model": "stats.countryalias", + "pk": 183 + }, + { + "fields": { + "alias": "PT", + "country": "PT" + }, + "model": "stats.countryalias", + "pk": 184 + }, + { + "fields": { + "alias": "PW", + "country": "PW" + }, + "model": "stats.countryalias", + "pk": 185 + }, + { + "fields": { + "alias": "PY", + "country": "PY" + }, + "model": "stats.countryalias", + "pk": 186 + }, + { + "fields": { + "alias": "QA", + "country": "QA" + }, + "model": "stats.countryalias", + "pk": 187 + }, + { + "fields": { + "alias": "RE", + "country": "RE" + }, + "model": "stats.countryalias", + "pk": 188 + }, + { + "fields": { + "alias": "RO", + "country": "RO" + }, + "model": "stats.countryalias", + "pk": 189 + }, + { + "fields": { + "alias": "RS", + "country": "RS" + }, + "model": "stats.countryalias", + "pk": 190 + }, + { + "fields": { + "alias": "RU", + "country": "RU" + }, + "model": "stats.countryalias", + "pk": 191 + }, + { + "fields": { + "alias": "RW", + "country": "RW" + }, + "model": "stats.countryalias", + "pk": 192 + }, + { + "fields": { + "alias": "SA", + "country": "SA" + }, + "model": "stats.countryalias", + "pk": 193 + }, + { + "fields": { + "alias": "SB", + "country": "SB" + }, + "model": "stats.countryalias", + "pk": 194 + }, + { + "fields": { + "alias": "SC", + "country": "SC" + }, + "model": "stats.countryalias", + "pk": 195 + }, + { + "fields": { + "alias": "SD", + "country": "SD" + }, + "model": "stats.countryalias", + "pk": 196 + }, + { + "fields": { + "alias": "SE", + "country": "SE" + }, + "model": "stats.countryalias", + "pk": 197 + }, + { + "fields": { + "alias": "SG", + "country": "SG" + }, + "model": "stats.countryalias", + "pk": 198 + }, + { + "fields": { + "alias": "SH", + "country": "SH" + }, + "model": "stats.countryalias", + "pk": 199 + }, + { + "fields": { + "alias": "SI", + "country": "SI" + }, + "model": "stats.countryalias", + "pk": 200 + }, + { + "fields": { + "alias": "SJ", + "country": "SJ" + }, + "model": "stats.countryalias", + "pk": 201 + }, + { + "fields": { + "alias": "SK", + "country": "SK" + }, + "model": "stats.countryalias", + "pk": 202 + }, + { + "fields": { + "alias": "SL", + "country": "SL" + }, + "model": "stats.countryalias", + "pk": 203 + }, + { + "fields": { + "alias": "SM", + "country": "SM" + }, + "model": "stats.countryalias", + "pk": 204 + }, + { + "fields": { + "alias": "SN", + "country": "SN" + }, + "model": "stats.countryalias", + "pk": 205 + }, + { + "fields": { + "alias": "SO", + "country": "SO" + }, + "model": "stats.countryalias", + "pk": 206 + }, + { + "fields": { + "alias": "SR", + "country": "SR" + }, + "model": "stats.countryalias", + "pk": 207 + }, + { + "fields": { + "alias": "SS", + "country": "SS" + }, + "model": "stats.countryalias", + "pk": 208 + }, + { + "fields": { + "alias": "ST", + "country": "ST" + }, + "model": "stats.countryalias", + "pk": 209 + }, + { + "fields": { + "alias": "SV", + "country": "SV" + }, + "model": "stats.countryalias", + "pk": 210 + }, + { + "fields": { + "alias": "SX", + "country": "SX" + }, + "model": "stats.countryalias", + "pk": 211 + }, + { + "fields": { + "alias": "SY", + "country": "SY" + }, + "model": "stats.countryalias", + "pk": 212 + }, + { + "fields": { + "alias": "SZ", + "country": "SZ" + }, + "model": "stats.countryalias", + "pk": 213 + }, + { + "fields": { + "alias": "TC", + "country": "TC" + }, + "model": "stats.countryalias", + "pk": 214 + }, + { + "fields": { + "alias": "TD", + "country": "TD" + }, + "model": "stats.countryalias", + "pk": 215 + }, + { + "fields": { + "alias": "TF", + "country": "TF" + }, + "model": "stats.countryalias", + "pk": 216 + }, + { + "fields": { + "alias": "TG", + "country": "TG" + }, + "model": "stats.countryalias", + "pk": 217 + }, + { + "fields": { + "alias": "TH", + "country": "TH" + }, + "model": "stats.countryalias", + "pk": 218 + }, + { + "fields": { + "alias": "TJ", + "country": "TJ" + }, + "model": "stats.countryalias", + "pk": 219 + }, + { + "fields": { + "alias": "TK", + "country": "TK" + }, + "model": "stats.countryalias", + "pk": 220 + }, + { + "fields": { + "alias": "TL", + "country": "TL" + }, + "model": "stats.countryalias", + "pk": 221 + }, + { + "fields": { + "alias": "TM", + "country": "TM" + }, + "model": "stats.countryalias", + "pk": 222 + }, + { + "fields": { + "alias": "TN", + "country": "TN" + }, + "model": "stats.countryalias", + "pk": 223 + }, + { + "fields": { + "alias": "TO", + "country": "TO" + }, + "model": "stats.countryalias", + "pk": 224 + }, + { + "fields": { + "alias": "TR", + "country": "TR" + }, + "model": "stats.countryalias", + "pk": 225 + }, + { + "fields": { + "alias": "TT", + "country": "TT" + }, + "model": "stats.countryalias", + "pk": 226 + }, + { + "fields": { + "alias": "TV", + "country": "TV" + }, + "model": "stats.countryalias", + "pk": 227 + }, + { + "fields": { + "alias": "TW", + "country": "TW" + }, + "model": "stats.countryalias", + "pk": 228 + }, + { + "fields": { + "alias": "TZ", + "country": "TZ" + }, + "model": "stats.countryalias", + "pk": 229 + }, + { + "fields": { + "alias": "UA", + "country": "UA" + }, + "model": "stats.countryalias", + "pk": 230 + }, + { + "fields": { + "alias": "UG", + "country": "UG" + }, + "model": "stats.countryalias", + "pk": 231 + }, + { + "fields": { + "alias": "UM", + "country": "UM" + }, + "model": "stats.countryalias", + "pk": 232 + }, + { + "fields": { + "alias": "US", + "country": "US" + }, + "model": "stats.countryalias", + "pk": 233 + }, + { + "fields": { + "alias": "UY", + "country": "UY" + }, + "model": "stats.countryalias", + "pk": 234 + }, + { + "fields": { + "alias": "UZ", + "country": "UZ" + }, + "model": "stats.countryalias", + "pk": 235 + }, + { + "fields": { + "alias": "VA", + "country": "VA" + }, + "model": "stats.countryalias", + "pk": 236 + }, + { + "fields": { + "alias": "VC", + "country": "VC" + }, + "model": "stats.countryalias", + "pk": 237 + }, + { + "fields": { + "alias": "VE", + "country": "VE" + }, + "model": "stats.countryalias", + "pk": 238 + }, + { + "fields": { + "alias": "VG", + "country": "VG" + }, + "model": "stats.countryalias", + "pk": 239 + }, + { + "fields": { + "alias": "VI", + "country": "VI" + }, + "model": "stats.countryalias", + "pk": 240 + }, + { + "fields": { + "alias": "VN", + "country": "VN" + }, + "model": "stats.countryalias", + "pk": 241 + }, + { + "fields": { + "alias": "VU", + "country": "VU" + }, + "model": "stats.countryalias", + "pk": 242 + }, + { + "fields": { + "alias": "WF", + "country": "WF" + }, + "model": "stats.countryalias", + "pk": 243 + }, + { + "fields": { + "alias": "WS", + "country": "WS" + }, + "model": "stats.countryalias", + "pk": 244 + }, + { + "fields": { + "alias": "YE", + "country": "YE" + }, + "model": "stats.countryalias", + "pk": 245 + }, + { + "fields": { + "alias": "YT", + "country": "YT" + }, + "model": "stats.countryalias", + "pk": 246 + }, + { + "fields": { + "alias": "ZA", + "country": "ZA" + }, + "model": "stats.countryalias", + "pk": 247 + }, + { + "fields": { + "alias": "ZM", + "country": "ZM" + }, + "model": "stats.countryalias", + "pk": 248 + }, + { + "fields": { + "alias": "ZW", + "country": "ZW" + }, + "model": "stats.countryalias", + "pk": 249 + }, + { + "fields": { + "alias": "russian federation", + "country": "RU" + }, + "model": "stats.countryalias", + "pk": 250 + }, + { + "fields": { + "alias": "p. r. china", + "country": "CN" + }, + "model": "stats.countryalias", + "pk": 251 + }, + { + "fields": { + "alias": "p.r. china", + "country": "CN" + }, + "model": "stats.countryalias", + "pk": 252 + }, + { + "fields": { + "alias": "p.r.china", + "country": "CN" + }, + "model": "stats.countryalias", + "pk": 253 + }, + { + "fields": { + "alias": "p.r china", + "country": "CN" + }, + "model": "stats.countryalias", + "pk": 254 + }, + { + "fields": { + "alias": "p.r. of china", + "country": "CN" + }, + "model": "stats.countryalias", + "pk": 255 + }, + { + "fields": { + "alias": "PRC", + "country": "CN" + }, + "model": "stats.countryalias", + "pk": 256 + }, + { + "fields": { + "alias": "P.R.C", + "country": "CN" + }, + "model": "stats.countryalias", + "pk": 257 + }, + { + "fields": { + "alias": "P.R.C.", + "country": "CN" + }, + "model": "stats.countryalias", + "pk": 258 + }, + { + "fields": { + "alias": "beijing", + "country": "CN" + }, + "model": "stats.countryalias", + "pk": 259 + }, + { + "fields": { + "alias": "shenzhen", + "country": "CN" + }, + "model": "stats.countryalias", + "pk": 260 + }, + { + "fields": { + "alias": "R.O.C.", + "country": "TW" + }, + "model": "stats.countryalias", + "pk": 261 + }, + { + "fields": { + "alias": "usa", + "country": "US" + }, + "model": "stats.countryalias", + "pk": 262 + }, + { + "fields": { + "alias": "UAS", + "country": "US" + }, + "model": "stats.countryalias", + "pk": 263 + }, + { + "fields": { + "alias": "USA.", + "country": "US" + }, + "model": "stats.countryalias", + "pk": 264 + }, + { + "fields": { + "alias": "u.s.a.", + "country": "US" + }, + "model": "stats.countryalias", + "pk": 265 + }, + { + "fields": { + "alias": "u. s. a.", + "country": "US" + }, + "model": "stats.countryalias", + "pk": 266 + }, + { + "fields": { + "alias": "u.s.a", + "country": "US" + }, + "model": "stats.countryalias", + "pk": 267 + }, + { + "fields": { + "alias": "u.s.", + "country": "US" + }, + "model": "stats.countryalias", + "pk": 268 + }, + { + "fields": { + "alias": "U.S", + "country": "GB" + }, + "model": "stats.countryalias", + "pk": 269 + }, + { + "fields": { + "alias": "US of A", + "country": "US" + }, + "model": "stats.countryalias", + "pk": 270 + }, + { + "fields": { + "alias": "united sates", + "country": "US" + }, + "model": "stats.countryalias", + "pk": 271 + }, + { + "fields": { + "alias": "united state", + "country": "US" + }, + "model": "stats.countryalias", + "pk": 272 + }, + { + "fields": { + "alias": "united states", + "country": "US" + }, + "model": "stats.countryalias", + "pk": 273 + }, + { + "fields": { + "alias": "unites states", + "country": "US" + }, + "model": "stats.countryalias", + "pk": 274 + }, + { + "fields": { + "alias": "texas", + "country": "US" + }, + "model": "stats.countryalias", + "pk": 275 + }, + { + "fields": { + "alias": "UK", + "country": "GB" + }, + "model": "stats.countryalias", + "pk": 276 + }, + { + "fields": { + "alias": "united kingcom", + "country": "GB" + }, + "model": "stats.countryalias", + "pk": 277 + }, + { + "fields": { + "alias": "great britain", + "country": "GB" + }, + "model": "stats.countryalias", + "pk": 278 + }, + { + "fields": { + "alias": "england", + "country": "GB" + }, + "model": "stats.countryalias", + "pk": 279 + }, + { + "fields": { + "alias": "U.K.", + "country": "GB" + }, + "model": "stats.countryalias", + "pk": 280 + }, + { + "fields": { + "alias": "U.K", + "country": "GB" + }, + "model": "stats.countryalias", + "pk": 281 + }, + { + "fields": { + "alias": "scotland", + "country": "GB" + }, + "model": "stats.countryalias", + "pk": 282 + }, + { + "fields": { + "alias": "republic of korea", + "country": "KR" + }, + "model": "stats.countryalias", + "pk": 283 + }, + { + "fields": { + "alias": "korea", + "country": "KR" + }, + "model": "stats.countryalias", + "pk": 284 + }, + { + "fields": { + "alias": "korea rep", + "country": "KR" + }, + "model": "stats.countryalias", + "pk": 285 + }, + { + "fields": { + "alias": "korea (the republic of)", + "country": "KR" + }, + "model": "stats.countryalias", + "pk": 286 + }, + { + "fields": { + "alias": "the netherlands", + "country": "NL" + }, + "model": "stats.countryalias", + "pk": 287 + }, + { + "fields": { + "alias": "netherland", + "country": "NL" + }, + "model": "stats.countryalias", + "pk": 288 + }, + { + "fields": { + "alias": "danmark", + "country": "DK" + }, + "model": "stats.countryalias", + "pk": 289 + }, + { + "fields": { + "alias": "sweeden", + "country": "SE" + }, + "model": "stats.countryalias", + "pk": 290 + }, + { + "fields": { + "alias": "swede", + "country": "SE" + }, + "model": "stats.countryalias", + "pk": 291 + }, + { + "fields": { + "alias": "belgique", + "country": "BE" + }, + "model": "stats.countryalias", + "pk": 292 + }, + { + "fields": { + "alias": "madrid", + "country": "ES" + }, + "model": "stats.countryalias", + "pk": 293 + }, + { + "fields": { + "alias": "espana", + "country": "ES" + }, + "model": "stats.countryalias", + "pk": 294 + }, + { + "fields": { + "alias": "hellas", + "country": "GR" + }, + "model": "stats.countryalias", + "pk": 295 + }, + { + "fields": { + "alias": "gemany", + "country": "DE" + }, + "model": "stats.countryalias", + "pk": 296 + }, + { + "fields": { + "alias": "deutschland", + "country": "DE" + }, + "model": "stats.countryalias", + "pk": 297 + }, + { + "fields": { + "alias": "italia", + "country": "IT" + }, + "model": "stats.countryalias", + "pk": 298 + }, + { + "fields": { + "alias": "isreal", + "country": "IL" + }, + "model": "stats.countryalias", + "pk": 299 + }, + { + "fields": { + "alias": "tel aviv", + "country": "IL" + }, + "model": "stats.countryalias", + "pk": 300 + }, + { + "fields": { + "alias": "UAE", + "country": "AE" + }, + "model": "stats.countryalias", + "pk": 301 + }, + { + "fields": { + "alias": "grand-duchy of luxembourg", + "country": "LU" + }, + "model": "stats.countryalias", + "pk": 302 + }, + { + "fields": { + "alias": "brasil", + "country": "BR" + }, + "model": "stats.countryalias", + "pk": 303 + }, { "fields": { "command": "xym", "switch": "--version", - "time": "2019-04-28T00:08:08.288", + "time": "2019-06-05T00:08:14.315", "used": true, "version": "xym 0.4" }, @@ -10949,7 +13373,7 @@ "fields": { "command": "pyang", "switch": "--version", - "time": "2019-04-28T00:08:09.335", + "time": "2019-06-05T00:08:15.692", "used": true, "version": "pyang 1.7.8" }, @@ -10960,7 +13384,7 @@ "fields": { "command": "yanglint", "switch": "--version", - "time": "2019-04-28T00:08:09.623", + "time": "2019-06-05T00:08:15.932", "used": true, "version": "yanglint 0.14.80" }, @@ -10971,7 +13395,7 @@ "fields": { "command": "xml2rfc", "switch": "--version", - "time": "2019-04-28T00:08:11.596", + "time": "2019-06-05T00:08:18.757", "used": true, "version": "xml2rfc 2.22.3" }, diff --git a/ietf/review/migrations/0011_review_document2_fk.py b/ietf/review/migrations/0011_review_document2_fk.py new file mode 100644 index 000000000..7e6a9d4f2 --- /dev/null +++ b/ietf/review/migrations/0011_review_document2_fk.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-08 11:58 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0015_1_add_fk_to_document_id'), + ('review', '0010_populate_review_assignments'), + ] + + operations = [ + migrations.AddField( + model_name='reviewrequest', + name='doc2', + field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reviewrequest_set', to='doc.Document', to_field=b'id'), + ), + migrations.AddField( + model_name='reviewwish', + name='doc2', + field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'), + ), + migrations.AddField( + model_name='reviewrequest', + name='unused_review2', + field=ietf.utils.models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='id'), + ), + migrations.AddField( + model_name='reviewassignment', + name='review2', + field=ietf.utils.models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='id'), + ), + migrations.AlterField( + model_name='reviewrequest', + name='doc', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_revreq', to='doc.Document', to_field=b'name'), + ), + migrations.AlterField( + model_name='reviewwish', + name='doc', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_revwish', to='doc.Document', to_field=b'name'), + ), + migrations.AlterField( + model_name='reviewrequest', + name='unused_review', + field=ietf.utils.models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='old_unused_review', to='doc.Document', to_field=b'name'), + ), + migrations.AlterField( + model_name='reviewassignment', + name='review', + field=ietf.utils.models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='old_reviewassignment', to='doc.Document', to_field=b'name'), + ), + ] diff --git a/ietf/review/migrations/0012_remove_old_document_field.py b/ietf/review/migrations/0012_remove_old_document_field.py new file mode 100644 index 000000000..eea4899dd --- /dev/null +++ b/ietf/review/migrations/0012_remove_old_document_field.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-20 09:53 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('review', '0011_review_document2_fk'), + ] + + operations = [ + migrations.RemoveField( + model_name='reviewrequest', + name='doc', + ), + migrations.RemoveField( + model_name='reviewrequest', + name='unused_reviewer', + ), + migrations.RemoveField( + model_name='reviewrequest', + name='unused_review', + ), + migrations.RemoveField( + model_name='reviewrequest', + name='unused_review2', + ), + migrations.RemoveField( + model_name='reviewrequest', + name='unused_reviewed_rev', + ), + migrations.RemoveField( + model_name='reviewrequest', + name='unused_result', + ), + migrations.RemoveField( + model_name='reviewwish', + name='doc', + ), + migrations.RemoveField( + model_name='reviewassignment', + name='review', + ), + ] diff --git a/ietf/review/migrations/0013_rename_field_document2.py b/ietf/review/migrations/0013_rename_field_document2.py new file mode 100644 index 000000000..b40b82fd1 --- /dev/null +++ b/ietf/review/migrations/0013_rename_field_document2.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-21 05:31 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0019_rename_field_document2'), + ('review', '0012_remove_old_document_field'), + ] + + operations = [ + migrations.RenameField( + model_name='reviewrequest', + old_name='doc2', + new_name='doc', + ), + migrations.RenameField( + model_name='reviewwish', + old_name='doc2', + new_name='doc', + ), + migrations.RenameField( + model_name='reviewassignment', + old_name='review2', + new_name='review', + ), + ] diff --git a/ietf/review/migrations/0014_document_primary_key_cleanup.py b/ietf/review/migrations/0014_document_primary_key_cleanup.py new file mode 100644 index 000000000..8ef0b334e --- /dev/null +++ b/ietf/review/migrations/0014_document_primary_key_cleanup.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-06-10 03:47 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('review', '0013_rename_field_document2'), + ] + + operations = [ + migrations.AlterField( + model_name='reviewrequest', + name='doc', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviewrequest_set', to='doc.Document'), + ), + migrations.AlterField( + model_name='reviewwish', + name='doc', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), + ), + ] diff --git a/ietf/review/models.py b/ietf/review/models.py index dab758d50..3780e7667 100644 --- a/ietf/review/models.py +++ b/ietf/review/models.py @@ -119,14 +119,6 @@ class ReviewRequest(models.Model): requested_rev = models.CharField(verbose_name="requested revision", max_length=16, blank=True, help_text="Fill in if a specific revision is to be reviewed, e.g. 02") comment = models.TextField(verbose_name="Requester's comments and instructions", max_length=2048, blank=True, help_text="Provide any additional information to show to the review team secretary and reviewer", default='') - # Moved to class ReviewAssignment: - # These exist only to facilitate data migrations. They will be removed in the next release. - unused_reviewer = ForeignKey(Email, blank=True, null=True) - - unused_review = OneToOneField(Document, blank=True, null=True) - unused_reviewed_rev = models.CharField(verbose_name="reviewed revision", max_length=16, blank=True) - unused_result = ForeignKey(ReviewResultName, blank=True, null=True) - def __unicode__(self): return u"%s review on %s by %s %s" % (self.type, self.doc, self.team, self.state) diff --git a/ietf/review/utils.py b/ietf/review/utils.py index 5cef81fbe..5b8ce5bc5 100644 --- a/ietf/review/utils.py +++ b/ietf/review/utils.py @@ -167,7 +167,7 @@ def days_needed_to_fulfill_min_interval_for_reviewers(team): return res ReviewAssignmentData = namedtuple("ReviewAssignmentData", [ - "assignment_pk", "doc", "doc_pages", "req_time", "state", "assigned_time", "deadline", "reviewed_rev", "result", "team", "reviewer", + "assignment_pk", "doc_name", "doc_pages", "req_time", "state", "assigned_time", "deadline", "reviewed_rev", "result", "team", "reviewer", "late_days", "request_to_assignment_days", "assignment_to_closure_days", "request_to_closure_days"]) @@ -194,7 +194,7 @@ def extract_review_assignment_data(teams=None, reviewers=None, time_from=None, t event_qs = ReviewAssignment.objects.filter(filters) event_qs = event_qs.values_list( - "pk", "review_request__doc", "review_request__doc__pages", "review_request__time", "state", "review_request__deadline", "reviewed_rev", "result", "review_request__team", + "pk", "review_request__doc__name", "review_request__doc__pages", "review_request__time", "state", "review_request__deadline", "reviewed_rev", "result", "review_request__team", "reviewer__person", "assigned_on", "completed_on" ) @@ -215,7 +215,7 @@ def extract_review_assignment_data(teams=None, reviewers=None, time_from=None, t for assignment in event_qs: - assignment_pk, doc, doc_pages, req_time, state, deadline, reviewed_rev, result, team, reviewer, assigned_on, completed_on = assignment + assignment_pk, doc_name, doc_pages, req_time, state, deadline, reviewed_rev, result, team, reviewer, assigned_on, completed_on = assignment requested_time = req_time assigned_time = assigned_on @@ -226,7 +226,7 @@ def extract_review_assignment_data(teams=None, reviewers=None, time_from=None, t assignment_to_closure_days = positive_days(assigned_time, closed_time) request_to_closure_days = positive_days(requested_time, closed_time) - d = ReviewAssignmentData(assignment_pk, doc, doc_pages, req_time, state, assigned_time, deadline, reviewed_rev, result, team, reviewer, + d = ReviewAssignmentData(assignment_pk, doc_name, doc_pages, req_time, state, assigned_time, deadline, reviewed_rev, result, team, reviewer, late_days, request_to_assignment_days, assignment_to_closure_days, request_to_closure_days) @@ -659,7 +659,7 @@ def suggested_review_requests_for_team(team): # cancelled/moved telechat_events = TelechatDocEvent.objects.filter( # turn into list so we don't get a complex and slow join sent down to the DB - doc__in=list(telechat_docs.values_list("pk", flat=True)), + doc__id__in=list(telechat_docs.values_list("pk", flat=True)), ).values_list( "doc", "pk", "time", "telechat_date" ).order_by("doc", "-time", "-id").distinct() @@ -688,7 +688,7 @@ def suggested_review_requests_for_team(team): # filter those with existing explicit requests existing_requests = defaultdict(list) - for r in ReviewRequest.objects.filter(doc__in=requests.iterkeys(), team=team): + for r in ReviewRequest.objects.filter(doc__id__in=requests.iterkeys(), team=team): existing_requests[r.doc_id].append(r) def blocks(existing, request): @@ -719,8 +719,10 @@ def extract_revision_ordered_review_assignments_for_documents_and_replaced(revie replaces = extract_complete_replaces_ancestor_mapping_for_docs(names) assignments_for_each_doc = defaultdict(list) - for r in review_assignment_queryset.filter(review_request__doc__in=set(e for l in replaces.itervalues() for e in l) | names).order_by("-reviewed_rev","-assigned_on", "-id").iterator(): - assignments_for_each_doc[r.review_request.doc_id].append(r) + replacement_name_set = set(e for l in replaces.itervalues() for e in l) | names + for r in ( review_assignment_queryset.filter(review_request__doc__name__in=replacement_name_set) + .order_by("-reviewed_rev","-assigned_on", "-id").iterator()): + assignments_for_each_doc[r.review_request.doc.name].append(r) # now collect in breadth-first order to keep the revision order intact res = defaultdict(list) @@ -765,8 +767,8 @@ def extract_revision_ordered_review_requests_for_documents_and_replaced(review_r replaces = extract_complete_replaces_ancestor_mapping_for_docs(names) requests_for_each_doc = defaultdict(list) - for r in review_request_queryset.filter(doc__in=set(e for l in replaces.itervalues() for e in l) | names).order_by("-time", "-id").iterator(): - requests_for_each_doc[r.doc_id].append(r) + for r in review_request_queryset.filter(doc__name__in=set(e for l in replaces.itervalues() for e in l) | names).order_by("-time", "-id").iterator(): + requests_for_each_doc[r.doc.name].append(r) # now collect in breadth-first order to keep the revision order intact res = defaultdict(list) @@ -990,12 +992,12 @@ def email_reviewer_reminder(review_request): deadline_days = (review_request.deadline - datetime.date.today()).days - subject = "Reminder: deadline for review of {} in {} is {}".format(review_request.doc_id, team.acronym, review_request.deadline.isoformat()) + subject = "Reminder: deadline for review of {} in {} is {}".format(review_request.doc.name, team.acronym, review_request.deadline.isoformat()) import ietf.ietfauth.views overview_url = urlreverse(ietf.ietfauth.views.review_overview) import ietf.doc.views_review - request_url = urlreverse(ietf.doc.views_review.review_request, kwargs={ "name": review_request.doc_id, "request_id": review_request.pk }) + request_url = urlreverse(ietf.doc.views_review.review_request, kwargs={ "name": review_request.doc.name, "request_id": review_request.pk }) domain = Site.objects.get_current().domain @@ -1034,12 +1036,12 @@ def email_secretary_reminder(review_request, secretary_role): deadline_days = (review_request.deadline - datetime.date.today()).days - subject = "Reminder: deadline for review of {} in {} is {}".format(review_request.doc_id, team.acronym, review_request.deadline.isoformat()) + subject = "Reminder: deadline for review of {} in {} is {}".format(review_request.doc.name, team.acronym, review_request.deadline.isoformat()) import ietf.group.views settings_url = urlreverse(ietf.group.views.change_review_secretary_settings, kwargs={ "acronym": team.acronym, "group_type": team.type_id }) import ietf.doc.views_review - request_url = urlreverse(ietf.doc.views_review.review_request, kwargs={ "name": review_request.doc_id, "request_id": review_request.pk }) + request_url = urlreverse(ietf.doc.views_review.review_request, kwargs={ "name": review_request.doc.name, "request_id": review_request.pk }) domain = Site.objects.get_current().domain diff --git a/ietf/secr/proceedings/proc_utils.py b/ietf/secr/proceedings/proc_utils.py index 549d37237..f696c5e27 100644 --- a/ietf/secr/proceedings/proc_utils.py +++ b/ietf/secr/proceedings/proc_utils.py @@ -207,10 +207,10 @@ def get_progress_stats(sdate,edate): new_draft_events = events.filter(newrevisiondocevent__rev='00') new_drafts = list(set([ e.doc_id for e in new_draft_events ])) data['new_drafts_count'] = len(new_drafts) - data['new_drafts_updated_count'] = events.filter(doc__in=new_drafts,newrevisiondocevent__rev='01').count() - data['new_drafts_updated_more_count'] = events.filter(doc__in=new_drafts,newrevisiondocevent__rev='02').count() + data['new_drafts_updated_count'] = events.filter(doc__id__in=new_drafts,newrevisiondocevent__rev='01').count() + data['new_drafts_updated_more_count'] = events.filter(doc__id__in=new_drafts,newrevisiondocevent__rev='02').count() - update_events = events.filter(type='new_revision').exclude(doc__in=new_drafts) + update_events = events.filter(type='new_revision').exclude(doc__id__in=new_drafts) data['updated_drafts_count'] = len(set([ e.doc_id for e in update_events ])) # Calculate Final Four Weeks stats (ffw) @@ -224,7 +224,7 @@ def get_progress_stats(sdate,edate): data['ffw_new_count'] = ffw_new_count data['ffw_new_percent'] = ffw_new_percent - ffw_update_events = events.filter(time__gte=ffwdate,type='new_revision').exclude(doc__in=new_drafts) + ffw_update_events = events.filter(time__gte=ffwdate,type='new_revision').exclude(doc__id__in=new_drafts) ffw_update_count = len(set([ e.doc_id for e in ffw_update_events ])) try: ffw_update_percent = format(ffw_update_count / float(data['updated_drafts_count']),'.0%') diff --git a/ietf/settings.py b/ietf/settings.py index 2fb58bfa3..68ecd17b5 100644 --- a/ietf/settings.py +++ b/ietf/settings.py @@ -21,6 +21,7 @@ warnings.filterwarnings("ignore", message="Deprecated allow_tags attribute used warnings.filterwarnings("ignore", message="You passed a bytestring as `filenames`. This will not work on Python 3.") warnings.filterwarnings("ignore", message="django.forms.extras is deprecated.", module="bootstrap3") warnings.filterwarnings("ignore", message="defusedxml.lxml is no longer supported and will be removed in a future release.", module="tastypie") +warnings.filterwarnings("ignore", message="Duplicate index '.*' defined on the table") try: diff --git a/ietf/submit/migrations/0002_submission_document2_fk.py b/ietf/submit/migrations/0002_submission_document2_fk.py new file mode 100644 index 000000000..23ef204e4 --- /dev/null +++ b/ietf/submit/migrations/0002_submission_document2_fk.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-08 11:58 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0015_1_add_fk_to_document_id'), + ('submit', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='submission', + name='draft2', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'), + ), + migrations.AlterField( + model_name='submission', + name='draft', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='old_submission', to='doc.Document', to_field=b'name'), + ), + ] diff --git a/ietf/submit/migrations/0003_remove_old_document_field.py b/ietf/submit/migrations/0003_remove_old_document_field.py new file mode 100644 index 000000000..20b35fca9 --- /dev/null +++ b/ietf/submit/migrations/0003_remove_old_document_field.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-25 06:44 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('submit', '0002_submission_document2_fk'), + ] + + operations = [ + migrations.RemoveField( + model_name='submission', + name='draft', + ), + ] diff --git a/ietf/submit/migrations/0004_rename_field_document2.py b/ietf/submit/migrations/0004_rename_field_document2.py new file mode 100644 index 000000000..9ff0f6d42 --- /dev/null +++ b/ietf/submit/migrations/0004_rename_field_document2.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-25 06:46 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0019_rename_field_document2'), + ('submit', '0003_remove_old_document_field'), + ] + + operations = [ + migrations.RenameField( + model_name='submission', + old_name='draft2', + new_name='draft', + ), + ] diff --git a/ietf/submit/tests.py b/ietf/submit/tests.py index 50cbcceb8..7f978d4a5 100644 --- a/ietf/submit/tests.py +++ b/ietf/submit/tests.py @@ -181,7 +181,7 @@ class SubmitTests(TestCase): if r.status_code == 302: submission = Submission.objects.get(name=name) self.assertEqual(submission.submitter, email.utils.formataddr((submitter_name, submitter_email))) - self.assertEqual(submission.replaces, ",".join(d.name for d in DocAlias.objects.filter(pk__in=replaces.split(",") if replaces else []))) + self.assertEqual(submission.replaces, ",".join(d.name for d in DocAlias.objects.filter(name__in=replaces.split(",") if replaces else []))) return r @@ -237,7 +237,7 @@ class SubmitTests(TestCase): mailbox_before = len(outbox) replaced_alias = draft.docalias_set.first() r = self.supply_extra_metadata(name, status_url, author.ascii, author.email().address.lower(), - replaces=str(replaced_alias.pk) + "," + str(sug_replaced_alias.pk)) + replaces=str(replaced_alias.name) + "," + str(sug_replaced_alias.name)) self.assertEqual(r.status_code, 302) status_url = r["Location"] @@ -594,16 +594,16 @@ class SubmitTests(TestCase): status_url, author = self.do_submission(name,rev) mailbox_before = len(outbox) replaced_alias = draft.docalias_set.first() - r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=str(replaced_alias.pk)) + r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=str(replaced_alias.name)) self.assertEqual(r.status_code, 200) self.assertTrue('cannot replace itself' in unicontent(r)) replaced_alias = DocAlias.objects.get(name='draft-ietf-random-thing') - r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=str(replaced_alias.pk)) + r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=str(replaced_alias.name)) self.assertEqual(r.status_code, 200) self.assertTrue('cannot replace an RFC' in unicontent(r)) replaced_alias.document.set_state(State.objects.get(type='draft-iesg',slug='approved')) replaced_alias.document.set_state(State.objects.get(type='draft',slug='active')) - r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=str(replaced_alias.pk)) + r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=str(replaced_alias.name)) self.assertEqual(r.status_code, 200) self.assertTrue('approved by the IESG and cannot' in unicontent(r)) r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces='') @@ -737,7 +737,7 @@ class SubmitTests(TestCase): "edit-pages": "123", "submitter-name": "Some Random Test Person", "submitter-email": "random@example.com", - "replaces": str(draft.docalias_set.all().first().pk), + "replaces": str(draft.docalias_set.all().first().name), "edit-note": "no comments", "authors-0-name": "Person 1", "authors-0-email": "person1@example.com", diff --git a/ietf/sync/tests.py b/ietf/sync/tests.py index 171bcd065..134c307ac 100644 --- a/ietf/sync/tests.py +++ b/ietf/sync/tests.py @@ -478,7 +478,7 @@ class RFCEditorUndoTests(TestCase): # get r = self.client.get(url) self.assertEqual(r.status_code, 200) - self.assertTrue(e2.doc_id in unicontent(r)) + self.assertTrue(e2.doc.name in unicontent(r)) # delete e2 deleted_before = DeletedEvent.objects.count() diff --git a/ietf/templates/community/notification_email.txt b/ietf/templates/community/notification_email.txt index 0fc1c662c..9581423f0 100644 --- a/ietf/templates/community/notification_email.txt +++ b/ietf/templates/community/notification_email.txt @@ -4,7 +4,7 @@ Hello, This is a notification from the {{ clist.long_name }}. Document: {{ event.doc }}, -https://datatracker.ietf.org/doc/{{ event.doc_id }}/ +https://datatracker.ietf.org/doc/{{ event.doc.name }}/ Change by {{ event.by }} on {{ event.time }}: diff --git a/ietf/templates/doc/document_review.html b/ietf/templates/doc/document_review.html index efa13552f..30c0f7f60 100644 --- a/ietf/templates/doc/document_review.html +++ b/ietf/templates/doc/document_review.html @@ -44,7 +44,7 @@ diff --git a/ietf/templates/doc/review_assignment_summary.html b/ietf/templates/doc/review_assignment_summary.html index e6e9bcca6..de4e82040 100644 --- a/ietf/templates/doc/review_assignment_summary.html +++ b/ietf/templates/doc/review_assignment_summary.html @@ -1,12 +1,12 @@
{% if review_assignment.state_id == "completed" or review_assignment.state_id == "part-completed" %} - - {{ review_assignment.review_request.team.acronym|upper }} {{ review_assignment.review_request.type.name }} Review{% if review_assignment.reviewed_rev and review_assignment.reviewed_rev != current_rev or review_assignment.review_request.doc_id != current_doc_name %} (of {% if review_assignment.review_request.doc_id != current_doc_name %}{{ review_assignment.review_request.doc_id }}{% endif %}-{{ review_assignment.reviewed_rev }}){% endif %}{% if review_assignment.result %}: + + {{ review_assignment.review_request.team.acronym|upper }} {{ review_assignment.review_request.type.name }} Review{% if review_assignment.reviewed_rev and review_assignment.reviewed_rev != current_rev or review_assignment.review_request.doc.name != current_doc_name %} (of {% if review_assignment.review_request.doc.name != current_doc_name %}{{ review_assignment.review_request.doc.name }}{% endif %}-{{ review_assignment.reviewed_rev }}){% endif %}{% if review_assignment.result %}: {{ review_assignment.result.name }}{% endif %} {% if review_assignment.state_id == "part-completed" %}(partially completed){% endif %} {% else %} - {{ review_assignment.review_request.team.acronym|upper }} {{ review_assignment.review_request.type.name }} Review + {{ review_assignment.review_request.team.acronym|upper }} {{ review_assignment.review_request.type.name }} Review - due: {{ review_assignment.review_request.deadline|date:"Y-m-d" }} {% endif %}
diff --git a/ietf/templates/group/manage_review_requests.html b/ietf/templates/group/manage_review_requests.html index 2da532d96..12f3f1030 100644 --- a/ietf/templates/group/manage_review_requests.html +++ b/ietf/templates/group/manage_review_requests.html @@ -61,13 +61,13 @@ {% for rlatest in r.latest_reqs %}
{% if rlatest.reviewed_rev %} - Previous review of {% if rlatest.doc_id != r.doc_id %}{{ rlatest.doc_id }}{% endif %}-{{ rlatest.reviewed_rev }} + Previous review of {% if rlatest.doc_id != r.doc_id %}{{ rlatest.doc.name }}{% endif %}-{{ rlatest.reviewed_rev }} (diff): {% if rlatest.result %}{{ rlatest.result.name }}{% else %}result unavail.{% endif %} by {{ rlatest.reviewer.person }}{% if rlatest.closed_review_request_event %} {{ rlatest.closed_review_request_event.time.date|date }}{% endif %} {% else %} - Previous review of {% if rlatest.doc_id != r.doc_id %}{{ rlatest.doc_id }}{% else %}this document{% endif %}: - {% if rlatest.result %}{{ rlatest.result.name }}{% else %}result unavail.{% endif %} + Previous review of {% if rlatest.doc_id != r.doc_id %}{{ rlatest.doc.name }}{% else %}this document{% endif %}: + {% if rlatest.result %}{{ rlatest.result.name }}{% else %}result unavail.{% endif %} by {{ rlatest.reviewer.person }}{% if rlatest.closed_review_request_event %} {{ rlatest.closed_review_request_event.time.date|date }}{% endif %} {% endif %}
diff --git a/ietf/templates/iesg/agenda_doc.txt b/ietf/templates/iesg/agenda_doc.txt index c5700d795..247d456a5 100644 --- a/ietf/templates/iesg/agenda_doc.txt +++ b/ietf/templates/iesg/agenda_doc.txt @@ -6,6 +6,6 @@ IANA Review: {{ doc.iana_review_state }}{% endif %}{% if doc.consensus %} Consensus: {{ doc.consensus }}{% endif %}{% if doc.lastcall_expires %} Last call expires: {{ doc.lastcall_expires|date:"Y-m-d" }}{% endif %}{% if doc.review_assignments %} - Reviews: {% for assignment in doc.review_assignments %}{% with current_doc_name=doc.name current_rev=doc.rev %}{% if not forloop.first %} {% endif %}{{ assignment.review_request.team.acronym|upper }} {{ assignment.review_request.type.name }} Review{% if assignment.state_id == "completed" or assignment.state_id == "part-completed" %}{% if assignment.reviewed_rev and assignment.reviewed_rev != current_rev or assignment.review_request.doc_id != current_doc_name %} (of {% if assignment.review_request.doc_id != current_doc_name %}{{ assignment.review_request.doc_id }}{% endif %}-{{ assignment.reviewed_rev }}){% endif %}{% if assignment.result %}: {{ assignment.result.name }}{% endif %} {% if assignment.state_id == "part-completed" %}(partially completed){% endif %}{% else %} - due: {{ assignment.review_request.deadline|date:"Y-m-d" }}{% endif %}{% endwith %} + Reviews: {% for assignment in doc.review_assignments %}{% with current_doc_name=doc.name current_rev=doc.rev %}{% if not forloop.first %} {% endif %}{{ assignment.review_request.team.acronym|upper }} {{ assignment.review_request.type.name }} Review{% if assignment.state_id == "completed" or assignment.state_id == "part-completed" %}{% if assignment.reviewed_rev and assignment.reviewed_rev != current_rev or assignment.review_request.doc.name != current_doc_name %} (of {% if assignment.review_request.doc.name != current_doc_name %}{{ assignment.review_request.doc.name }}{% endif %}-{{ assignment.reviewed_rev }}){% endif %}{% if assignment.result %}: {{ assignment.result.name }}{% endif %} {% if assignment.state_id == "part-completed" %}(partially completed){% endif %}{% else %} - due: {{ assignment.review_request.deadline|date:"Y-m-d" }}{% endif %}{% endwith %} {% endfor %}{% endif %} {% with doc.active_defer_event as defer %}{% if defer %} Was deferred by {{defer.by}} on {{defer.time|date:"Y-m-d"}}{% endif %}{% endwith %} diff --git a/ietf/templates/ietfauth/review_overview.html b/ietf/templates/ietfauth/review_overview.html index e79259a5b..4a48d7d65 100644 --- a/ietf/templates/ietfauth/review_overview.html +++ b/ietf/templates/ietfauth/review_overview.html @@ -95,7 +95,7 @@
{% for review_assignment in other_reviews %} - {% include "doc/review_assignment_summary.html" with current_doc_name=review_assignemnt.review_request.doc_id current_rev=review_assignment.reviewed_rev %} + {% include "doc/review_assignment_summary.html" with current_doc_name=review_assignemnt.review_request.doc.name current_rev=review_assignment.reviewed_rev %} {% endfor %}
{% for w in review_wishes %} - + - +
{{ w.doc_id }}{{ w.doc_id }} {{ w.team.acronym }}
diff --git a/ietf/templates/review/reviewer_reminder.txt b/ietf/templates/review/reviewer_reminder.txt index d2fe608cf..a15306d9b 100644 --- a/ietf/templates/review/reviewer_reminder.txt +++ b/ietf/templates/review/reviewer_reminder.txt @@ -1,4 +1,4 @@ -{% load ietf_filters %}{% autoescape off %}{% filter wordwrap:78 %}This is just a friendly reminder that the deadline for the review of {{ review_request.doc_id }} is in {{ deadline_days }} day{{ deadline_days|pluralize }}: +{% load ietf_filters %}{% autoescape off %}{% filter wordwrap:78 %}This is just a friendly reminder that the deadline for the review of {{ review_request.doc.name }} is in {{ deadline_days }} day{{ deadline_days|pluralize }}: {{ review_request_url }} diff --git a/ietf/templates/review/secretary_reminder.txt b/ietf/templates/review/secretary_reminder.txt index 2361489f3..5315b3646 100644 --- a/ietf/templates/review/secretary_reminder.txt +++ b/ietf/templates/review/secretary_reminder.txt @@ -1,4 +1,4 @@ -{% load ietf_filters %}{% autoescape off %}{% filter wordwrap:78 %}This is just a friendly reminder that the deadline for the review of {{ review_request.doc_id }} is in {{ deadline_days }} day{{ deadline_days|pluralize }}: +{% load ietf_filters %}{% autoescape off %}{% filter wordwrap:78 %}This is just a friendly reminder that the deadline for the review of {{ review_request.doc.name }} is in {{ deadline_days }} day{{ deadline_days|pluralize }}: {{ review_request_url }} diff --git a/ietf/templates/sync/rfceditor_undo.html b/ietf/templates/sync/rfceditor_undo.html index 50a3ab951..4f4e319d5 100644 --- a/ietf/templates/sync/rfceditor_undo.html +++ b/ietf/templates/sync/rfceditor_undo.html @@ -22,7 +22,7 @@ {% for e in events %}
{{ e.time|date:"Y-m-d H:i:s"}}{{ e.doc_id }}{{ e.doc.name }} {{ e.desc|safe }} diff --git a/ietf/utils/history.py b/ietf/utils/history.py index 85e65024d..992902572 100644 --- a/ietf/utils/history.py +++ b/ietf/utils/history.py @@ -1,3 +1,8 @@ +# Copyright The IETF Trust 2011-2019, All Rights Reserved +# -*- coding: utf-8 -*- + +import debug # pyflakes:ignore + def find_history_active_at(obj, time): """Assumes obj has a corresponding history model (e.g. obj could be Document with a corresponding DocHistory model), then either diff --git a/ietf/utils/test_runner.py b/ietf/utils/test_runner.py index 8bd818ce1..5482de9f7 100644 --- a/ietf/utils/test_runner.py +++ b/ietf/utils/test_runner.py @@ -64,6 +64,7 @@ from django.template import TemplateDoesNotExist from django.template.loaders.base import Loader as BaseLoader from django.test.runner import DiscoverRunner from django.core.management import call_command + from django.urls import RegexURLResolver import debug # pyflakes:ignore @@ -72,7 +73,9 @@ debug.debug = True import ietf import ietf.utils.mail from ietf.checks import maybe_create_svn_symlinks +from ietf.utils.management.commands import pyflakes from ietf.utils.test_smtpserver import SMTPTestServerDriver +from ietf.utils.test_utils import TestCase loaded_templates = set() @@ -121,6 +124,19 @@ def safe_destroy_test_db(*args, **kwargs): settings.DATABASES["default"]["NAME"] = test_database_name return old_destroy(*args, **kwargs) +class PyFlakesTestCase(TestCase): + + def __init__(self, test_runner=None, **kwargs): + self.runner = test_runner + super(PyFlakesTestCase, self).__init__(**kwargs) + + def pyflakes_test(self): + self.maxDiff = None + path = os.path.join(settings.BASE_DIR) + warnings = [] + warnings = pyflakes.checkPaths([path], verbosity=0) + self.assertEqual([], [str(w) for w in warnings]) + class TemplateCoverageLoader(BaseLoader): is_usable = True @@ -375,6 +391,8 @@ class CoverageTest(unittest.TestCase): self.skipTest("Coverage switched off with --skip-coverage") def interleaved_migrations_test(self): + if self.runner.permit_mixed_migrations: + return # from django.apps import apps # unreleased = {} # for appconf in apps.get_app_configs(): @@ -474,12 +492,16 @@ class IetfTestRunner(DiscoverRunner): parser.add_argument('--html-report', action='store_true', default=False, help='Generate a html code coverage report in %s' % settings.TEST_CODE_COVERAGE_REPORT_DIR) + parser.add_argument('--permit-mixed-migrations', + action='store_true', default=False, + help='Permit interleaved unreleased migrations') - def __init__(self, skip_coverage=False, save_version_coverage=None, html_report=None, **kwargs): + def __init__(self, skip_coverage=False, save_version_coverage=None, html_report=None, permit_mixed_migrations=None, **kwargs): # self.check_coverage = not skip_coverage self.save_version_coverage = save_version_coverage self.html_report = html_report + self.permit_mixed_migrations = permit_mixed_migrations # self.root_dir = os.path.dirname(settings.BASE_DIR) self.coverage_file = os.path.join(self.root_dir, settings.TEST_COVERAGE_MASTER_FILE) @@ -668,6 +690,7 @@ class IetfTestRunner(DiscoverRunner): code_coverage_collection = True url_coverage_collection = True extra_tests += [ + PyFlakesTestCase(test_runner=self, methodName='pyflakes_test'), CoverageTest(test_runner=self, methodName='interleaved_migrations_test'), CoverageTest(test_runner=self, methodName='url_coverage_test'), CoverageTest(test_runner=self, methodName='template_coverage_test'), @@ -679,7 +702,7 @@ class IetfTestRunner(DiscoverRunner): # parent classes to later subclasses, the parent classes will # determine the ordering, so use the most specific classes # necessary to get the right ordering: - self.reorder_by += (StaticLiveServerTestCase, TemplateTagTest, CoverageTest, ) + self.reorder_by = (PyFlakesTestCase, ) + self.reorder_by + (StaticLiveServerTestCase, TemplateTagTest, CoverageTest, ) failures = super(IetfTestRunner, self).run_tests(test_labels, extra_tests=extra_tests, **kwargs) diff --git a/ietf/utils/tests.py b/ietf/utils/tests.py index ee318c30f..a23adab7d 100644 --- a/ietf/utils/tests.py +++ b/ietf/utils/tests.py @@ -37,7 +37,6 @@ from ietf.utils.bower_storage import BowerStorageFinder from ietf.utils.draft import Draft, getmeta from ietf.utils.log import unreachable, assertion from ietf.utils.mail import send_mail_preformatted, send_mail_text, send_mail_mime, outbox -from ietf.utils.management.commands import pyflakes from ietf.utils.test_runner import get_template_paths, set_coverage_checking from ietf.utils.test_utils import TestCase @@ -51,15 +50,6 @@ except ImportError as e: skip_message = "Skipping trac tests: %s" % e sys.stderr.write(" "+skip_message+'\n') -class PyFlakesTestCase(TestCase): - - def test_pyflakes(self): - self.maxDiff = None - path = os.path.join(settings.BASE_DIR) - warnings = [] - warnings = pyflakes.checkPaths([path], verbosity=0) - self.assertEqual([], [str(w) for w in warnings]) - class SendingMail(TestCase): def test_send_mail_preformatted(self):