diff options
Diffstat (limited to 'news')
| -rw-r--r-- | news/admin.py | 9 | ||||
| -rw-r--r-- | news/migrations/0001_initial.py | 48 | ||||
| -rw-r--r-- | news/migrations/0002_move_news_in.py | 66 | ||||
| -rw-r--r-- | news/migrations/0003_new_date_columns_precision.py | 73 | ||||
| -rw-r--r-- | news/migrations/0004_auto__add_field_news_slug.py | 66 | ||||
| -rw-r--r-- | news/migrations/0005_add_slugs.py | 78 | ||||
| -rw-r--r-- | news/migrations/0006_auto__chg_field_news_slug.py | 66 | ||||
| -rw-r--r-- | news/models.py | 39 | ||||
| -rw-r--r-- | news/urls.py | 24 | ||||
| -rw-r--r-- | news/views.py | 127 |
10 files changed, 147 insertions, 449 deletions
diff --git a/news/admin.py b/news/admin.py index 1b7de1d8..562c16d4 100644 --- a/news/admin.py +++ b/news/admin.py @@ -2,9 +2,14 @@ from django.contrib import admin from .models import News + class NewsAdmin(admin.ModelAdmin): - list_display = ('title', 'author', 'postdate', 'last_modified') - list_filter = ('postdate', 'author') + list_display = ('title', 'author', 'postdate', 'last_modified', 'safe_mode') + list_filter = ('postdate', 'author', 'safe_mode') search_fields = ('title', 'content') + date_hierarchy = 'postdate' + admin.site.register(News, NewsAdmin) + +# vim: set ts=4 sw=4 et: diff --git a/news/migrations/0001_initial.py b/news/migrations/0001_initial.py index e30bf5c9..fc6b6cfb 100644 --- a/news/migrations/0001_initial.py +++ b/news/migrations/0001_initial.py @@ -1,21 +1,37 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models +# -*- coding: utf-8 -*- +from __future__ import unicode_literals -class Migration(SchemaMigration): +from django.db import models, migrations +import django.db.models.deletion +from django.conf import settings - def forwards(self, orm): - pass +class Migration(migrations.Migration): - def backwards(self, orm): - pass + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] - - models = { - - } - - complete_apps = ['news'] + operations = [ + migrations.CreateModel( + name='News', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('slug', models.SlugField(unique=True, max_length=255)), + ('postdate', models.DateTimeField(verbose_name=b'post date', db_index=True)), + ('last_modified', models.DateTimeField(editable=False, db_index=True)), + ('title', models.CharField(max_length=255)), + ('guid', models.CharField(max_length=255, editable=False)), + ('content', models.TextField()), + ('safe_mode', models.BooleanField(default=True)), + ('author', models.ForeignKey(related_name=b'news_author', on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ('-postdate',), + 'db_table': 'news', + 'verbose_name_plural': 'news', + 'get_latest_by': 'postdate', + }, + bases=(models.Model,), + ), + ] diff --git a/news/migrations/0002_move_news_in.py b/news/migrations/0002_move_news_in.py deleted file mode 100644 index d6dafad4..00000000 --- a/news/migrations/0002_move_news_in.py +++ /dev/null @@ -1,66 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - depends_on = ( - ('main', '0001_initial'), - ) - - def forwards(self, orm): - pass - - def backwards(self, orm): - pass - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'news.news': { - 'Meta': {'ordering': "['-postdate', '-id']", 'object_name': 'News', 'db_table': "'news'"}, - 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'news_author'", 'to': "orm['auth.User']"}), - 'content': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'postdate': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - } - } - - complete_apps = ['news'] diff --git a/news/migrations/0003_new_date_columns_precision.py b/news/migrations/0003_new_date_columns_precision.py deleted file mode 100644 index 21b64443..00000000 --- a/news/migrations/0003_new_date_columns_precision.py +++ /dev/null @@ -1,73 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Adding field 'News.last_modified' - db.add_column('news', 'last_modified', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, default=datetime.datetime.now(), db_index=True, blank=True), keep_default=False) - # Changing field 'News.postdate' - db.alter_column('news', 'postdate', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True)) - # Adding index on 'News', fields ['postdate'] - db.create_index('news', ['postdate']) - - def backwards(self, orm): - # Removing index on 'News', fields ['postdate'] - db.delete_index('news', ['postdate']) - # Deleting field 'News.last_modified' - db.delete_column('news', 'last_modified') - # Changing field 'News.postdate' - db.alter_column('news', 'postdate', self.gf('django.db.models.fields.DateField')(auto_now_add=True)) - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'news.news': { - 'Meta': {'ordering': "['-postdate', '-id']", 'object_name': 'News', 'db_table': "'news'"}, - 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'news_author'", 'to': "orm['auth.User']"}), - 'content': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}), - 'postdate': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - } - } - - complete_apps = ['news'] diff --git a/news/migrations/0004_auto__add_field_news_slug.py b/news/migrations/0004_auto__add_field_news_slug.py deleted file mode 100644 index 7e5dcb79..00000000 --- a/news/migrations/0004_auto__add_field_news_slug.py +++ /dev/null @@ -1,66 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Adding field 'News.slug' - db.add_column('news', 'slug', self.gf('django.db.models.fields.SlugField')(max_length=255, unique=True, null=True, db_index=True), keep_default=False) - - def backwards(self, orm): - # Deleting field 'News.slug' - db.delete_column('news', 'slug') - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'news.news': { - 'Meta': {'ordering': "['-postdate']", 'object_name': 'News', 'db_table': "'news'"}, - 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'news_author'", 'to': "orm['auth.User']"}), - 'content': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}), - 'postdate': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'unique': 'True', 'null': 'True', 'db_index': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - } - } - - complete_apps = ['news'] diff --git a/news/migrations/0005_add_slugs.py b/news/migrations/0005_add_slugs.py deleted file mode 100644 index 2a3b6174..00000000 --- a/news/migrations/0005_add_slugs.py +++ /dev/null @@ -1,78 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import DataMigration -from django.db import models - -from django.template.defaultfilters import slugify - -class Migration(DataMigration): - - def forwards(self, orm): - existing = list(orm.News.objects.values_list( - 'slug', flat=True).distinct()) - for item in orm.News.objects.all(): - suffixed = slug = slugify(item.title) - suffix = 1 - while suffixed in existing: - suffix += 1 - suffixed = "%s-%d" % (slug, suffix) - - item.slug = suffixed - existing.append(suffixed) - - item.save() - - def backwards(self, orm): - orm.News.obects.all.update(slug=None) - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'news.news': { - 'Meta': {'ordering': "['-postdate']", 'object_name': 'News', 'db_table': "'news'"}, - 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'news_author'", 'to': "orm['auth.User']"}), - 'content': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}), - 'postdate': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'unique': 'True', 'null': 'True', 'db_index': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - } - } - - complete_apps = ['news'] diff --git a/news/migrations/0006_auto__chg_field_news_slug.py b/news/migrations/0006_auto__chg_field_news_slug.py deleted file mode 100644 index c6c61e84..00000000 --- a/news/migrations/0006_auto__chg_field_news_slug.py +++ /dev/null @@ -1,66 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Changing field 'News.slug' - db.alter_column('news', 'slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=255)) - - def backwards(self, orm): - # Changing field 'News.slug' - db.alter_column('news', 'slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=255, null=True)) - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'news.news': { - 'Meta': {'ordering': "['-postdate']", 'object_name': 'News', 'db_table': "'news'"}, - 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'news_author'", 'to': "orm['auth.User']"}), - 'content': ('django.db.models.fields.TextField', [], {}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}), - 'postdate': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - } - } - - complete_apps = ['news'] diff --git a/news/models.py b/news/models.py index 6c8a7039..a66da8d4 100644 --- a/news/models.py +++ b/news/models.py @@ -1,19 +1,29 @@ from django.db import models from django.contrib.auth.models import User +from django.contrib.sites.models import Site +from django.utils.safestring import mark_safe +from django.utils.timezone import now + +from main.utils import parse_markdown + class News(models.Model): - id = models.AutoField(primary_key=True) slug = models.SlugField(max_length=255, unique=True) - author = models.ForeignKey(User, related_name='news_author') - postdate = models.DateTimeField("post date", auto_now_add=True, db_index=True) - last_modified = models.DateTimeField(editable=False, - auto_now=True, db_index=True) + author = models.ForeignKey(User, related_name='news_author', + on_delete=models.PROTECT) + postdate = models.DateTimeField("post date", db_index=True) + last_modified = models.DateTimeField(editable=False, db_index=True) title = models.CharField(max_length=255) + guid = models.CharField(max_length=255, editable=False) content = models.TextField() + safe_mode = models.BooleanField(default=True) def get_absolute_url(self): return '/news/%s/' % self.slug + def html(self): + return mark_safe(parse_markdown(self.content, not self.safe_mode)) + def __unicode__(self): return self.title @@ -21,6 +31,23 @@ class News(models.Model): db_table = 'news' verbose_name_plural = 'news' get_latest_by = 'postdate' - ordering = ['-postdate'] + ordering = ('-postdate',) + + +def set_news_fields(sender, **kwargs): + news = kwargs['instance'] + current_time = now() + news.last_modified = current_time + if not news.postdate: + news.postdate = current_time + # http://diveintomark.org/archives/2004/05/28/howto-atom-id + news.guid = 'tag:%s,%s:%s' % (Site.objects.get_current(), + current_time.strftime('%Y-%m-%d'), news.get_absolute_url()) + + +from django.db.models.signals import pre_save + +pre_save.connect(set_news_fields, sender=News, + dispatch_uid="news.models") # vim: set ts=4 sw=4 et: diff --git a/news/urls.py b/news/urls.py new file mode 100644 index 00000000..c13722d4 --- /dev/null +++ b/news/urls.py @@ -0,0 +1,24 @@ +from django.conf.urls import patterns +from django.contrib.auth.decorators import permission_required +from .views import (NewsDetailView, NewsListView, + NewsCreateView, NewsEditView, NewsDeleteView) + + +urlpatterns = patterns('news.views', + (r'^$', NewsListView.as_view(), {}, 'news-list'), + + (r'^preview/$', 'preview'), + # old news URLs, permanent redirect view so we don't break all links + (r'^(?P<object_id>\d+)/$', 'view_redirect'), + + (r'^add/$', + permission_required('news.add_news')(NewsCreateView.as_view())), + (r'^(?P<slug>[-\w]+)/$', + NewsDetailView.as_view()), + (r'^(?P<slug>[-\w]+)/edit/$', + permission_required('news.change_news')(NewsEditView.as_view())), + (r'^(?P<slug>[-\w]+)/delete/$', + permission_required('news.delete_news')(NewsDeleteView.as_view())), +) + +# vim: set ts=4 sw=4 et: diff --git a/news/views.py b/news/views.py index f3d7312f..274ba75d 100644 --- a/news/views.py +++ b/news/views.py @@ -1,91 +1,66 @@ from django import forms -from django.contrib.auth.decorators import permission_required from django.http import HttpResponse from django.shortcuts import get_object_or_404, redirect -from django.template.defaultfilters import slugify -from django.views.decorators.cache import never_cache -from django.views.generic import list_detail, create_update -from django.views.generic.simple import direct_to_template - -import markdown +from django.views.decorators.http import require_POST +from django.views.generic import (DetailView, ListView, + CreateView, UpdateView, DeleteView) from .models import News +from main.utils import find_unique_slug, parse_markdown + + +class NewsForm(forms.ModelForm): + class Meta: + model = News + exclude = ('id', 'slug', 'author', 'postdate', 'safe_mode') + + +class NewsDetailView(DetailView): + queryset = News.objects.all().select_related('author') + template_name = "news/view.html" + + +class NewsListView(ListView): + queryset = News.objects.all().select_related('author').defer('content') + template_name = "news/list.html" + paginate_by = 50 + + +class NewsCreateView(CreateView): + model = News + form_class = NewsForm + template_name = "news/add.html" + + def form_valid(self, form): + # special logic, we auto-fill the author and slug fields + newsitem = form.save(commit=False) + newsitem.author = self.request.user + newsitem.slug = find_unique_slug(News, newsitem.title) + newsitem.save() + return super(NewsCreateView, self).form_valid(form) + + +class NewsEditView(UpdateView): + model = News + form_class = NewsForm + template_name = "news/add.html" + + +class NewsDeleteView(DeleteView): + model = News + template_name = "news/delete.html" + success_url = "/news/" + def view_redirect(request, object_id): newsitem = get_object_or_404(News, pk=object_id) return redirect(newsitem, permanent=True) -def view(request, slug=None): - return list_detail.object_detail(request, News.objects.all(), - slug=slug, - template_name="news/view.html", - template_object_name='news') - -#TODO: May as well use a date-based list here sometime -def news_list(request): - return list_detail.object_list(request, - News.objects.all().select_related('author').defer('content'), - paginate_by=50, - template_name="news/list.html", - template_object_name="news") -class NewsForm(forms.ModelForm): - class Meta: - model = News - exclude=('id', 'slug', 'author', 'postdate') - -def find_unique_slug(newsitem): - '''Attempt to find a unique slug for this news item.''' - existing = list(News.objects.values_list('slug', flat=True).distinct()) - - suffixed = slug = slugify(newsitem.title) - suffix = 0 - while suffixed in existing: - suffix += 1 - suffixed = "%s-%d" % (slug, suffix) - - return suffixed - -@permission_required('news.add_news') -@never_cache -def add(request): - if request.POST: - form = NewsForm(request.POST) - if form.is_valid(): - newsitem = form.save(commit=False) - newsitem.author = request.user - newsitem.slug = find_unique_slug(newsitem) - newsitem.save() - return redirect(newsitem.get_absolute_url()) - else: - form = NewsForm() - return direct_to_template(request, 'news/add.html', { 'form': form }) - -@permission_required('news.delete_news') -@never_cache -def delete(request, slug): - return create_update.delete_object(request, - News, - slug=slug, - post_delete_redirect='/news/', - template_name='news/delete.html', - template_object_name='news') - -@permission_required('news.change_news') -@never_cache -def edit(request, slug): - return create_update.update_object(request, - slug=slug, - form_class=NewsForm, - template_name="news/add.html") - -@permission_required('news.change_news') -@never_cache +@require_POST def preview(request): - markup = '' - if request.POST: - data = request.POST.get('data', '') - markup = markdown.markdown(data) + data = request.POST.get('data', '') + markup = parse_markdown(data) return HttpResponse(markup) # vim: set ts=4 sw=4 et: |
