From 70f3a4e4dc634b3828937a95adcd8f29cab8a627 Mon Sep 17 00:00:00 2001 From: Sigve Sebastian Farstad Date: Tue, 1 Mar 2016 16:50:00 +0100 Subject: [PATCH 1/4] Force slugs to be uppercase We seem to have relied on an implicit constraint that slugs should be uppercase. This pull request makes this constraint more explicit by carefully transforming slugs to uppercase everywhere. --- wikipendium/wiki/views.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/wikipendium/wiki/views.py b/wikipendium/wiki/views.py index 3220dfda..ce7575d5 100644 --- a/wikipendium/wiki/views.py +++ b/wikipendium/wiki/views.py @@ -106,7 +106,7 @@ def add_tag_to_article(request, slug): if not request.POST: return HttpResponseBadRequest() - article = get_object_or_404(Article, slug=slug) + article = get_object_or_404(Article, slug=slug.upper()) if 'tag' not in request.POST: return HttpResponseBadRequest() @@ -163,7 +163,7 @@ def new(request, slug=None): form = NewArticleForm(request.POST) if form.is_valid(): slug = request.POST.get('slug') - article = Article(slug=slug) + article = Article(slug=slug.upper()) article.save() article_content = form.save(commit=False) @@ -174,9 +174,8 @@ def new(request, slug=None): else: article_content = None if slug: - slug = slug.upper() - article_content = ArticleContent(article=Article(slug=slug), - lang=None) + article_content = ArticleContent( + article=Article(slug=slug.upper()), lang=None) form = NewArticleForm(instance=article_content) return render(request, 'edit.html', { @@ -188,7 +187,7 @@ def new(request, slug=None): @login_required def add_language(request, slug, lang=None): - article = get_object_or_404(Article, slug=slug) + article = get_object_or_404(Article, slug=slug.upper()) if request.method == 'POST': form = AddLanguageArticleForm(article, request.POST) @@ -215,7 +214,7 @@ def add_language(request, slug, lang=None): @login_required def edit(request, slug, lang='en'): - article = get_object_or_404(Article, slug=slug) + article = get_object_or_404(Article, slug=slug.upper()) article_content = article.get_newest_content(lang) if request.method == 'POST': @@ -259,7 +258,7 @@ def preview(request): def history(request, slug, lang='en'): try: - article = Article.objects.get(slug=slug) + article = Article.objects.get(slug=slug.upper()) except: return no_article(request, slug.upper()) @@ -276,7 +275,7 @@ def history(request, slug, lang='en'): def history_single(request, slug, lang='en', id=None): try: - article = Article.objects.get(slug=slug) + article = Article.objects.get(slug=slug.upper()) except: return no_article(request, slug.upper()) @@ -306,7 +305,7 @@ def cacheable_history_single(request, ac, has_parent, def history_single_rendered(request, slug, lang='en', id=None): try: - Article.objects.get(slug=slug) + Article.objects.get(slug=slug.upper()) except: return no_article(request, slug.upper()) From 5dd1341b3ce33c0e61a7a74133594bc9a469d224 Mon Sep 17 00:00:00 2001 From: Sigve Sebastian Farstad Date: Tue, 1 Mar 2016 16:59:52 +0100 Subject: [PATCH 2/4] Add wikipendium.wiki AppConfig This is needed to be able to specify the wikipendium.wiki app by label in places where names cannot be properly parsed to contain dots, such as when doing makemigrations. --- wikipendium/wiki/__init__.py | 1 + wikipendium/wiki/apps.py | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 wikipendium/wiki/apps.py diff --git a/wikipendium/wiki/__init__.py b/wikipendium/wiki/__init__.py index e69de29b..9f83789f 100644 --- a/wikipendium/wiki/__init__.py +++ b/wikipendium/wiki/__init__.py @@ -0,0 +1 @@ +default_app_config = 'wikipendium.wiki.apps.WikiConfig' diff --git a/wikipendium/wiki/apps.py b/wikipendium/wiki/apps.py new file mode 100644 index 00000000..fcc45ba8 --- /dev/null +++ b/wikipendium/wiki/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class WikiConfig(AppConfig): + name = 'wikipendium.wiki' + label = 'wikipendium__wiki' From 58b9939752486b91ce7db966fd20753e75a6d64f Mon Sep 17 00:00:00 2001 From: Sigve Sebastian Farstad Date: Tue, 1 Mar 2016 17:06:25 +0100 Subject: [PATCH 3/4] Surgically backport app label into old migrations This should probably work fine. --- wikipendium/wiki/migrations/0001_initial.py | 6 +++--- wikipendium/wiki/migrations/0002_article_tags.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wikipendium/wiki/migrations/0001_initial.py b/wikipendium/wiki/migrations/0001_initial.py index b93246df..f696e3dd 100644 --- a/wikipendium/wiki/migrations/0001_initial.py +++ b/wikipendium/wiki/migrations/0001_initial.py @@ -31,10 +31,10 @@ class Migration(migrations.Migration): ('title', models.CharField(max_length=1024)), ('lang', models.CharField(default=b'en', max_length=2)), ('updated', models.DateTimeField()), - ('article', models.ForeignKey(to='wiki.Article')), - ('child', models.ForeignKey(related_name='child_ac', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='wiki.ArticleContent', null=True)), + ('article', models.ForeignKey(to='wikipendium__wiki.Article')), + ('child', models.ForeignKey(related_name='child_ac', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='wikipendium__wiki.ArticleContent', null=True)), ('edited_by', models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, blank=True, to=settings.AUTH_USER_MODEL, null=True)), - ('parent', models.ForeignKey(related_name='parent_ac', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='wiki.ArticleContent', null=True)), + ('parent', models.ForeignKey(related_name='parent_ac', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='wikipendium__wiki.ArticleContent', null=True)), ], options={ }, diff --git a/wikipendium/wiki/migrations/0002_article_tags.py b/wikipendium/wiki/migrations/0002_article_tags.py index 1b00e646..64524463 100644 --- a/wikipendium/wiki/migrations/0002_article_tags.py +++ b/wikipendium/wiki/migrations/0002_article_tags.py @@ -9,7 +9,7 @@ class Migration(migrations.Migration): dependencies = [ ('taggit', '0001_initial'), - ('wiki', '0001_initial'), + ('wikipendium__wiki', '0001_initial'), ] operations = [ From f2e2f442e98ff5abd733e79ed7581b512a7200ad Mon Sep 17 00:00:00 2001 From: Sigve Sebastian Farstad Date: Tue, 1 Mar 2016 17:07:08 +0100 Subject: [PATCH 4/4] Add data migration to uppercase all article slugs We currently assume that all article slugs are uppercase. However, prior to this commit, it was possible to create articles with lowercase slugs using the UI, which means that databases could at the point of this data contain invalid data, i.e. lowercased slugs. This commit introduces a data migration that uppercases all slugs, ensuring that the database is returned to a valid state. --- .../migrations/0003_auto_20160301_1703.py | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 wikipendium/wiki/migrations/0003_auto_20160301_1703.py diff --git a/wikipendium/wiki/migrations/0003_auto_20160301_1703.py b/wikipendium/wiki/migrations/0003_auto_20160301_1703.py new file mode 100644 index 00000000..fd3ab20c --- /dev/null +++ b/wikipendium/wiki/migrations/0003_auto_20160301_1703.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +def uppercase_all_article_slugs(apps, schema_editor): + Article = apps.get_model("wikipendium__wiki", "Article") + articles = Article.objects.all() + for article in articles: + if article.slug: + article.slug = article.slug.upper() + article.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('wikipendium__wiki', '0002_article_tags'), + ] + + operations = [ + migrations.RunPython(uppercase_all_article_slugs), + ]