Merged in [10111] from olau@iola.dk:

This fixes Javascript widgets working with DocAliases, such as the
replaces field in draft submission, to work better with Javascript
disabled. It also makes sense from a modelling perspective as the name
really is a unique key for the alias.

The actual transformation requires a series of migrations taking a
couple of minutes to complete. The actual switch to the key is done at
the end.
 - Legacy-Id: 10251
Note: SVN reference [10111] has been migrated to Git commit 8bca1b4b33
This commit is contained in:
Henrik Levkowetz 2015-10-19 20:06:13 +00:00
commit bd4cf3319a
14 changed files with 314 additions and 88 deletions

View file

@ -105,7 +105,7 @@ class DocHistoryAdmin(admin.ModelAdmin):
list_display = ['doc', 'rev', 'state', 'group', 'pages', 'intended_std_level', 'author_list', 'time']
search_fields = ['doc__name']
ordering = ['time', 'doc', 'rev']
raw_id_fields = ['doc', 'authors', 'related', 'group', 'shepherd', 'ad']
raw_id_fields = ['doc', 'authors', 'group', 'shepherd', 'ad']
def state(self, instance):
return instance.get_state()

View file

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('doc', '0005_auto_20150721_0230'),
]
operations = [
migrations.RemoveField(
model_name='dochistory',
name='related',
),
migrations.AddField(
model_name='relateddochistory',
name='target_name',
field=models.CharField(default=b'', max_length=255),
preserve_default=True,
),
migrations.AddField(
model_name='relateddocument',
name='target_name',
field=models.CharField(default=b'', max_length=255),
preserve_default=True,
),
]

View file

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
import django.db
def fill_in_docalias_relationship_names(apps, schema_editor):
with django.db.connection.cursor() as cursor:
cursor.execute("update doc_relateddocument join doc_docalias on doc_docalias.id = doc_relateddocument.target_id set doc_relateddocument.target_name = doc_docalias.name;")
cursor.execute("update doc_relateddochistory join doc_docalias on doc_docalias.id = doc_relateddochistory.target_id set doc_relateddochistory.target_name = doc_docalias.name;")
def noop(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
('doc', '0006_auto_20150929_0828'),
]
operations = [
migrations.RunPython(fill_in_docalias_relationship_names, noop)
]

View file

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('doc', '0007_auto_20150929_0840'),
]
operations = [
migrations.RemoveField(
model_name='relateddochistory',
name='target',
),
migrations.RenameField(
model_name='relateddochistory',
old_name='target_name',
new_name='target',
),
migrations.RemoveField(
model_name='relateddocument',
name='target',
),
migrations.RenameField(
model_name='relateddocument',
old_name='target_name',
new_name='target',
),
]

View file

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('doc', '0008_auto_20150930_0242'),
('ipr', '0006_auto_20150930_0235'),
]
operations = [
migrations.RemoveField(
model_name='docalias',
name='id',
),
migrations.AlterField(
model_name='docalias',
name='name',
field=models.CharField(max_length=255, serialize=False, primary_key=True),
preserve_default=True,
),
]

View file

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('doc', '0009_auto_20150930_0248'),
]
operations = [
migrations.AlterField(
model_name='relateddochistory',
name='target',
field=models.ForeignKey(related_name='reversely_related_document_history_set', to='doc.DocAlias'),
preserve_default=True,
),
migrations.AlterField(
model_name='relateddocument',
name='target',
field=models.ForeignKey(to='doc.DocAlias'),
preserve_default=True,
),
]

View file

@ -367,7 +367,6 @@ class DocumentAuthor(models.Model):
class Document(DocumentInfo):
name = models.CharField(max_length=255, primary_key=True) # immutable
#related = models.ManyToManyField('DocAlias', through=RelatedDocument, blank=True, related_name="reversely_related_document_set")
authors = models.ManyToManyField(Email, through=DocumentAuthor, blank=True)
def __unicode__(self):
@ -540,7 +539,6 @@ class DocHistory(DocumentInfo):
# canonical_name and replace the function on Document with a
# property
name = models.CharField(max_length=255)
related = models.ManyToManyField('DocAlias', through=RelatedDocHistory, blank=True)
authors = models.ManyToManyField(Email, through=DocHistoryAuthor, blank=True)
def __unicode__(self):
return unicode(self.doc.name)
@ -620,8 +618,8 @@ 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)
document = models.ForeignKey(Document)
name = models.CharField(max_length=255, db_index=True)
def __unicode__(self):
return "%s-->%s" % (self.name, self.document.name)
document_link = admin_link("document")

View file

@ -1,11 +1,11 @@
# Autogenerated by the mkresources management command 2014-12-14 19:50
# Autogenerated by the makeresources management command 2015-10-19 12:29 PDT
from tastypie.resources import ModelResource
from tastypie.fields import ToOneField, ToManyField, CharField
from tastypie.constants import ALL, ALL_WITH_RELATIONS
from tastypie.fields import ToOneField, ToManyField, CharField # pyflakes:ignore
from tastypie.constants import ALL, ALL_WITH_RELATIONS # pyflakes:ignore
from ietf import api
from ietf.doc.models import * # pyflakes:ignore
from ietf.doc.models import * # pyflakes:ignore
from ietf.name.resources import BallotPositionNameResource, DocTypeNameResource
@ -179,6 +179,53 @@ class StateDocEventResource(ModelResource):
}
api.doc.register(StateDocEventResource())
from ietf.person.resources import PersonResource, EmailResource
from ietf.group.resources import GroupResource
from ietf.name.resources import StdLevelNameResource, StreamNameResource, DocTypeNameResource, DocTagNameResource, IntendedStdLevelNameResource
class DocHistoryResource(ModelResource):
type = ToOneField(DocTypeNameResource, 'type', null=True)
stream = ToOneField(StreamNameResource, 'stream', null=True)
group = ToOneField(GroupResource, 'group', null=True)
intended_std_level = ToOneField(IntendedStdLevelNameResource, 'intended_std_level', null=True)
std_level = ToOneField(StdLevelNameResource, 'std_level', null=True)
ad = ToOneField(PersonResource, 'ad', null=True)
shepherd = ToOneField(EmailResource, 'shepherd', null=True)
doc = ToOneField(DocumentResource, 'doc')
states = ToManyField(StateResource, 'states', null=True)
tags = ToManyField(DocTagNameResource, 'tags', null=True)
authors = ToManyField(EmailResource, 'authors', null=True)
class Meta:
queryset = DocHistory.objects.all()
serializer = api.Serializer()
#resource_name = 'dochistory'
filtering = {
"id": ALL,
"time": ALL,
"title": ALL,
"abstract": ALL,
"rev": ALL,
"pages": ALL,
"order": ALL,
"expires": ALL,
"notify": ALL,
"external_url": ALL,
"note": ALL,
"internal_comments": ALL,
"name": ALL,
"type": ALL_WITH_RELATIONS,
"stream": ALL_WITH_RELATIONS,
"group": ALL_WITH_RELATIONS,
"intended_std_level": ALL_WITH_RELATIONS,
"std_level": ALL_WITH_RELATIONS,
"ad": ALL_WITH_RELATIONS,
"shepherd": ALL_WITH_RELATIONS,
"doc": ALL_WITH_RELATIONS,
"states": ALL_WITH_RELATIONS,
"tags": ALL_WITH_RELATIONS,
"authors": ALL_WITH_RELATIONS,
}
api.doc.register(DocHistoryResource())
from ietf.person.resources import PersonResource
class ConsensusDocEventResource(ModelResource):
by = ToOneField(PersonResource, 'by')
@ -207,7 +254,6 @@ class DocAliasResource(ModelResource):
serializer = api.Serializer()
#resource_name = 'docalias'
filtering = {
"id": ALL,
"name": ALL,
"document": ALL_WITH_RELATIONS,
}
@ -336,6 +382,22 @@ class InitialReviewDocEventResource(ModelResource):
}
api.doc.register(InitialReviewDocEventResource())
from ietf.person.resources import EmailResource
class DocHistoryAuthorResource(ModelResource):
document = ToOneField(DocHistoryResource, 'document')
author = ToOneField(EmailResource, 'author')
class Meta:
queryset = DocHistoryAuthor.objects.all()
serializer = api.Serializer()
#resource_name = 'dochistoryauthor'
filtering = {
"id": ALL,
"order": ALL,
"document": ALL_WITH_RELATIONS,
"author": ALL_WITH_RELATIONS,
}
api.doc.register(DocHistoryAuthorResource())
from ietf.person.resources import PersonResource
class BallotDocEventResource(ModelResource):
by = ToOneField(PersonResource, 'by')
@ -375,54 +437,22 @@ class RelatedDocumentResource(ModelResource):
}
api.doc.register(RelatedDocumentResource())
from ietf.person.resources import PersonResource, EmailResource
from ietf.group.resources import GroupResource
from ietf.name.resources import StdLevelNameResource, StreamNameResource, DocTypeNameResource, DocTagNameResource, IntendedStdLevelNameResource
class DocHistoryResource(ModelResource):
type = ToOneField(DocTypeNameResource, 'type', null=True)
stream = ToOneField(StreamNameResource, 'stream', null=True)
group = ToOneField(GroupResource, 'group', null=True)
intended_std_level = ToOneField(IntendedStdLevelNameResource, 'intended_std_level', null=True)
std_level = ToOneField(StdLevelNameResource, 'std_level', null=True)
ad = ToOneField(PersonResource, 'ad', null=True)
shepherd = ToOneField(EmailResource, 'shepherd', null=True)
doc = ToOneField(DocumentResource, 'doc')
states = ToManyField(StateResource, 'states', null=True)
tags = ToManyField(DocTagNameResource, 'tags', null=True)
related = ToManyField(DocAliasResource, 'related', null=True)
authors = ToManyField(EmailResource, 'authors', null=True)
from ietf.name.resources import DocRelationshipNameResource
class RelatedDocHistoryResource(ModelResource):
source = ToOneField(DocHistoryResource, 'source')
target = ToOneField(DocAliasResource, 'target')
relationship = ToOneField(DocRelationshipNameResource, 'relationship')
class Meta:
queryset = DocHistory.objects.all()
queryset = RelatedDocHistory.objects.all()
serializer = api.Serializer()
#resource_name = 'dochistory'
#resource_name = 'relateddochistory'
filtering = {
"id": ALL,
"time": ALL,
"title": ALL,
"abstract": ALL,
"rev": ALL,
"pages": ALL,
"order": ALL,
"expires": ALL,
"notify": ALL,
"external_url": ALL,
"note": ALL,
"internal_comments": ALL,
"name": ALL,
"type": ALL_WITH_RELATIONS,
"stream": ALL_WITH_RELATIONS,
"group": ALL_WITH_RELATIONS,
"intended_std_level": ALL_WITH_RELATIONS,
"std_level": ALL_WITH_RELATIONS,
"ad": ALL_WITH_RELATIONS,
"shepherd": ALL_WITH_RELATIONS,
"doc": ALL_WITH_RELATIONS,
"states": ALL_WITH_RELATIONS,
"tags": ALL_WITH_RELATIONS,
"related": ALL_WITH_RELATIONS,
"authors": ALL_WITH_RELATIONS,
"source": ALL_WITH_RELATIONS,
"target": ALL_WITH_RELATIONS,
"relationship": ALL_WITH_RELATIONS,
}
api.doc.register(DocHistoryResource())
api.doc.register(RelatedDocHistoryResource())
from ietf.person.resources import PersonResource
from ietf.name.resources import BallotPositionNameResource
@ -455,36 +485,3 @@ class BallotPositionDocEventResource(ModelResource):
}
api.doc.register(BallotPositionDocEventResource())
from ietf.person.resources import EmailResource
class DocHistoryAuthorResource(ModelResource):
document = ToOneField(DocHistoryResource, 'document')
author = ToOneField(EmailResource, 'author')
class Meta:
queryset = DocHistoryAuthor.objects.all()
serializer = api.Serializer()
#resource_name = 'dochistoryauthor'
filtering = {
"id": ALL,
"order": ALL,
"document": ALL_WITH_RELATIONS,
"author": ALL_WITH_RELATIONS,
}
api.doc.register(DocHistoryAuthorResource())
from ietf.name.resources import DocRelationshipNameResource
class RelatedDocHistoryResource(ModelResource):
source = ToOneField(DocHistoryResource, 'source')
target = ToOneField(DocAliasResource, 'target')
relationship = ToOneField(DocRelationshipNameResource, 'relationship')
class Meta:
queryset = RelatedDocHistory.objects.all()
serializer = api.Serializer()
#resource_name = 'relateddochistory'
filtering = {
"id": ALL,
"source": ALL_WITH_RELATIONS,
"target": ALL_WITH_RELATIONS,
"relationship": ALL_WITH_RELATIONS,
}
api.doc.register(RelatedDocHistoryResource())

View file

@ -1304,7 +1304,7 @@ class ChangeReplacesTests(TestCase):
RelatedDocument.objects.create(source=self.replacea, target=self.basea.docalias_set.first(),
relationship=DocRelationshipName.objects.get(slug="possibly-replaces"))
self.assertEqual(self.basea.get_state().slug,'active')
r = self.client.post(url, dict(replaces=str(DocAlias.objects.get(name=self.basea.name).id)))
r = self.client.post(url, dict(replaces=self.basea.name))
self.assertEqual(r.status_code, 302)
self.assertEqual(RelatedDocument.objects.filter(relationship__slug='replaces',source=self.replacea).count(),1)
self.assertEqual(Document.objects.get(name='draft-test-base-a').get_state().slug,'repl')
@ -1318,7 +1318,7 @@ class ChangeReplacesTests(TestCase):
# Post that says replaceboth replaces both base a and base b
url = urlreverse('doc_change_replaces', kwargs=dict(name=self.replaceboth.name))
self.assertEqual(self.baseb.get_state().slug,'expired')
r = self.client.post(url, dict(replaces=str(DocAlias.objects.get(name=self.basea.name).id) + "," + str(DocAlias.objects.get(name=self.baseb.name).id)))
r = self.client.post(url, dict(replaces=self.basea.name + "," + self.baseb.name))
self.assertEqual(r.status_code, 302)
self.assertEqual(Document.objects.get(name='draft-test-base-a').get_state().slug,'repl')
self.assertEqual(Document.objects.get(name='draft-test-base-b').get_state().slug,'repl')

View file

@ -124,7 +124,6 @@ class IndexTests(TestCase):
e = LastCallDocEvent.objects.create(doc=draft, type="sent_last_call", expires=datetime.datetime.now() + datetime.timedelta(days=14), by=draft.ad)
DocAlias.objects.create(name="rfc1234", document=draft)
t = get_fields(all_id2_txt())
self.assertEqual(t[11], e.expires.strftime("%Y-%m-%d"))

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('ipr', '0003_auto_20150430_0847'),
]
operations = [
migrations.AddField(
model_name='iprdocrel',
name='document_name',
field=models.CharField(default=b'', max_length=255),
preserve_default=True,
),
]

View file

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
import django.db
def fill_in_docalias_relationship_names(apps, schema_editor):
with django.db.connection.cursor() as cursor:
cursor.execute("update ipr_iprdocrel join doc_docalias on doc_docalias.id = ipr_iprdocrel.document_id set ipr_iprdocrel.document_name = doc_docalias.name;")
def noop(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
('ipr', '0004_iprdocrel_document_name'),
]
operations = [
migrations.RunPython(fill_in_docalias_relationship_names, noop)
]

View file

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('ipr', '0005_auto_20150930_0227'),
]
operations = [
migrations.RemoveField(
model_name='iprdisclosurebase',
name='docs',
),
migrations.RemoveField(
model_name='iprdocrel',
name='document',
),
migrations.RenameField(
model_name='iprdocrel',
old_name='document_name',
new_name='document',
),
]

View file

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('doc', '0010_auto_20150930_0251'),
('ipr', '0006_auto_20150930_0235'),
]
operations = [
migrations.AddField(
model_name='iprdisclosurebase',
name='docs',
field=models.ManyToManyField(to='doc.DocAlias', through='ipr.IprDocRel'),
preserve_default=True,
),
migrations.AlterField(
model_name='iprdocrel',
name='document',
field=models.ForeignKey(to='doc.DocAlias'),
preserve_default=True,
),
]