diff --git a/src/players/manager.py b/src/players/manager.py
index 9916928f5..b95c96284 100644
--- a/src/players/manager.py
+++ b/src/players/manager.py
@@ -4,7 +4,7 @@ The managers for the custom Player object and permissions.
import datetime
from functools import update_wrapper
-from django.contrib.auth.models import User
+from django.contrib.auth.models import UserManager
from src.typeclasses.managers import returns_typeclass_list, returns_typeclass, TypedObjectManager
from src.utils import logger
__all__ = ("PlayerManager",)
@@ -60,7 +60,7 @@ def returns_player(method):
return None
return update_wrapper(func, method)
-class PlayerManager(TypedObjectManager):
+class PlayerManager(TypedObjectManager, UserManager):
"""
This PlayerManager implements methods for searching
and manipulating Players directly from the database.
diff --git a/src/players/migrations/0003_auto__add_field_playerdb_db_cmdset_storage.py b/src/players/migrations/0003_auto__add_field_playerdb_db_cmdset_storage.py
index c089e1f8e..3169188d5 100644
--- a/src/players/migrations/0003_auto__add_field_playerdb_db_cmdset_storage.py
+++ b/src/players/migrations/0003_auto__add_field_playerdb_db_cmdset_storage.py
@@ -7,13 +7,13 @@ from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
-
+
# Adding field 'PlayerDB.db_cmdset_storage'
db.add_column('players_playerdb', 'db_cmdset_storage', self.gf('django.db.models.fields.TextField')(null=True), keep_default=False)
def backwards(self, orm):
-
+
# Deleting field 'PlayerDB.db_cmdset_storage'
db.delete_column('players_playerdb', 'db_cmdset_storage')
diff --git a/src/players/migrations/0020_add_playerdbtmp.py b/src/players/migrations/0020_add_playerdbtmp.py
new file mode 100644
index 000000000..8a5187731
--- /dev/null
+++ b/src/players/migrations/0020_add_playerdbtmp.py
@@ -0,0 +1,162 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models, connection
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding model 'PlayerDBtmp'
+ if "auth_user" in connection.introspection.table_names():
+ # auth_user exists ffrom before. Use that as a base.
+ db.rename_table('auth_user', 'players_playerdbtmp')
+ else:
+ # from-scratch creation; no auth_user table available. Create vanilla User table
+ db.create_table(u'players_playerdbtmp', (
+ (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('password', self.gf('django.db.models.fields.CharField')(max_length=128)),
+ ('last_login', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('is_superuser', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('username', self.gf('django.db.models.fields.CharField')(unique=True, max_length=30)),
+ ('first_name', self.gf('django.db.models.fields.CharField')(max_length=30, blank=True)),
+ ('last_name', self.gf('django.db.models.fields.CharField')(max_length=30, blank=True)),
+ ('email', self.gf('django.db.models.fields.EmailField')(max_length=75, blank=True)),
+ ('is_staff', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('is_active', self.gf('django.db.models.fields.BooleanField')(default=True)),
+ ('date_joined', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ))
+ db.send_create_signal(u'players', ['PlayerDBtmp'])
+
+ # Adding M2M table for field groups on 'PlayerDBtmp'
+ db.create_table(u'players_playerdbtmp_groups', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('playerdbtmp', models.ForeignKey(orm[u'players.playerdbtmp'], null=False)),
+ ('group', models.ForeignKey(orm[u'auth.group'], null=False))
+ ))
+ db.create_unique(u'players_playerdbtmp_groups', ['playerdbtmp_id', 'group_id'])
+
+ # Adding M2M table for field user_permissions on 'PlayerDBtmp'
+ db.create_table(u'players_playerdbtmp_user_permissions', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('playerdbtmp', models.ForeignKey(orm[u'players.playerdbtmp'], null=False)),
+ ('permission', models.ForeignKey(orm[u'auth.permission'], null=False))
+ ))
+ db.create_unique(u'players_playerdbtmp_user_permissions', ['playerdbtmp_id', 'permission_id'])
+
+ # Adding field 'PlayerDB.db_is_connected'
+ db.add_column(u'players_playerdb', 'db_is_connected',
+ self.gf('django.db.models.fields.BooleanField')(default=False),
+ keep_default=False)
+
+ # Adding field 'PlayerDB.db_cmdset_storage'
+ db.add_column(u'players_playerdb', 'db_cmdset_storage',
+ self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
+ keep_default=False)
+
+ # add Evennia-specific columns
+ db.add_column('players_playerdbtmp', 'db_key', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True, null=True))
+ db.add_column('players_playerdbtmp', 'db_typeclass_path', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
+ db.add_column('players_playerdbtmp', 'db_date_created', self.gf('django.db.models.fields.DateTimeField')(null=True, auto_now_add=True, blank=True))
+ db.add_column('players_playerdbtmp', 'db_permissions', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True, null=True))
+ db.add_column('players_playerdbtmp', 'db_lock_storage', self.gf('django.db.models.fields.TextField')(blank=True, null=True))
+ db.add_column('players_playerdbtmp', 'db_is_connected', self.gf('django.db.models.fields.BooleanField')(default=False))
+ db.add_column('players_playerdbtmp', 'db_cmdset_storage', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
+
+ def backwards(self, orm):
+ raise RuntimeError("Cannot revert migration")
+
+
+ models = {
+ u'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ u'auth.permission': {
+ 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ u'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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ u'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'}),
+ u'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'})
+ },
+ u'players.playerattribute': {
+ 'Meta': {'object_name': 'PlayerAttribute'},
+ 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}),
+ 'db_value': ('src.utils.picklefield.PickledObjectField', [], {'null': 'True'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+ },
+ u'players.playerdb': {
+ 'Meta': {'object_name': 'PlayerDB'},
+ 'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+ 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'db_is_connected': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+ 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
+ },
+ u'players.playerdbtmp': {
+ 'Meta': {'ordering': "['-db_date_created', 'id', 'db_typeclass_path', 'db_key']", 'object_name': 'PlayerDBtmp'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'db_is_connected': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+ 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+ 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+ '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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ u'players.playernick': {
+ 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'},
+ 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}),
+ 'db_real': ('django.db.models.fields.TextField', [], {}),
+ 'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+ }
+ }
+
+ complete_apps = ['players']
diff --git a/src/players/migrations/0021_copy_user_profile_to_tmp.py b/src/players/migrations/0021_copy_user_profile_to_tmp.py
new file mode 100644
index 000000000..030e6d21e
--- /dev/null
+++ b/src/players/migrations/0021_copy_user_profile_to_tmp.py
@@ -0,0 +1,118 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ "Write your forwards methods here."
+ # Note: Remember to use orm['appname.ModelName'] rather than "from appname.models..."
+ if not db.dry_run:
+ for profile in orm['players.PlayerDB'].objects.all():
+ plyr = orm['players.PlayerDBtmp'].objects.get(id=profile.user_id)
+ plyr.db_cmdset_storage = profile.db_cmdset_storage
+ plyr.db_date_created = profile.db_date_created
+ plyr.db_is_connected = profile.db_is_connected
+ plyr.db_key = profile.db_key
+ plyr.db_lock_storage = profile.db_lock_storage
+ plyr.db_typeclass_path = profile.db_typeclass_path
+ plyr.db_permissions = profile.db_permissions
+ plyr.save()
+
+ def backwards(self, orm):
+ "Write your backwards methods here."
+ raise RuntimeError("Cannot revert this migration.")
+
+ models = {
+ u'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ u'auth.permission': {
+ 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ u'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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ u'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'}),
+ u'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'})
+ },
+ u'players.playerattribute': {
+ 'Meta': {'object_name': 'PlayerAttribute'},
+ 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}),
+ 'db_value': ('src.utils.picklefield.PickledObjectField', [], {'null': 'True'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+ },
+ u'players.playerdb': {
+ 'Meta': {'object_name': 'PlayerDB'},
+ 'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+ 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'db_is_connected': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+ 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
+ },
+ u'players.playerdbtmp': {
+ 'Meta': {'ordering': "['-db_date_created', 'id', 'db_typeclass_path', 'db_key']", 'object_name': 'PlayerDBtmp'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+ 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+ '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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ u'players.playernick': {
+ 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'},
+ 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}),
+ 'db_real': ('django.db.models.fields.TextField', [], {}),
+ 'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+ }
+ }
+
+ complete_apps = ['players']
+ symmetrical = True
diff --git a/src/players/migrations/0022_delete_old_profile.py b/src/players/migrations/0022_delete_old_profile.py
new file mode 100644
index 000000000..dd1f7c2dd
--- /dev/null
+++ b/src/players/migrations/0022_delete_old_profile.py
@@ -0,0 +1,107 @@
+# -*- coding: 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):
+ db.delete_table('players_playerdb')
+
+ def backwards(self, orm):
+ raise RuntimeError("Cannot revert this migration")
+
+ models = {
+ u'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ u'auth.permission': {
+ 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ u'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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ u'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'}),
+ u'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'})
+ },
+ u'players.playerattribute': {
+ 'Meta': {'object_name': 'PlayerAttribute'},
+ 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}),
+ 'db_value': ('src.utils.picklefield.PickledObjectField', [], {'null': 'True'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+ },
+ u'players.playerdb': {
+ 'Meta': {'object_name': 'PlayerDB'},
+ 'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+ 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'db_is_connected': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+ 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
+ },
+ u'players.playerdbtmp': {
+ 'Meta': {'ordering': "['-db_date_created', 'id', 'db_typeclass_path', 'db_key']", 'object_name': 'PlayerDBtmp'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'db_is_connected': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+ 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+ 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+ '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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ u'players.playernick': {
+ 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'},
+ 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}),
+ 'db_real': ('django.db.models.fields.TextField', [], {}),
+ 'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+ }
+ }
+
+ complete_apps = ['players']
diff --git a/src/players/migrations/0023_rename_tmp_player_to_playerdb.py b/src/players/migrations/0023_rename_tmp_player_to_playerdb.py
new file mode 100644
index 000000000..1a942b8be
--- /dev/null
+++ b/src/players/migrations/0023_rename_tmp_player_to_playerdb.py
@@ -0,0 +1,101 @@
+# -*- coding: 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):
+ db.rename_table('players_PlayerDBtmp', 'players_PlayerDB')
+ db.send_create_signal('players', ['PlayerDB'])
+
+ def backwards(self, orm):
+ raise RuntimeError("Cannot revert this migration.")
+
+ models = {
+ u'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ u'auth.permission': {
+ 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ u'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'}),
+ u'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'})
+ },
+ u'players.playerattribute': {
+ 'Meta': {'object_name': 'PlayerAttribute'},
+ 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}),
+ 'db_value': ('src.utils.picklefield.PickledObjectField', [], {'null': 'True'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+ },
+# u'players.playerdbtmp': {
+# 'Meta': {'ordering': "['-db_date_created', 'id', 'db_typeclass_path', 'db_key']", 'object_name': 'PlayerDBtmp'},
+# 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+# 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+# 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+# 'db_is_connected': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+# 'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+# 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+# 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+# 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+# '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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+# u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+# 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+# },
+ u'players.playerdb': {
+ 'Meta': {'ordering': "['-db_date_created', 'id', 'db_typeclass_path', 'db_key']", 'object_name': 'PlayerDB'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+ 'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+ '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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ u'players.playernick': {
+ 'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'},
+ 'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['players.PlayerDB']"}),
+ 'db_real': ('django.db.models.fields.TextField', [], {}),
+ 'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+ }
+ }
+
+ complete_apps = ['players']
diff --git a/src/players/models.py b/src/players/models.py
index aaab60f7e..d3b46654e 100644
--- a/src/players/models.py
+++ b/src/players/models.py
@@ -25,7 +25,7 @@ account info and OOC account configuration variables etc.
from django.conf import settings
from django.db import models
-from django.contrib.auth.models import User
+from django.contrib.auth.models import AbstractUser, User
from django.utils.encoding import smart_str
from src.server.caches import get_field_cache, set_field_cache, del_field_cache
@@ -110,7 +110,8 @@ class PlayerNickHandler(TypeNickHandler):
#
#------------------------------------------------------------
-class PlayerDB(TypedObject):
+
+class PlayerDB(TypedObject, AbstractUser):
"""
This is a special model using Django's 'profile' functionality
and extends the default Django User model. It is defined as such
@@ -145,8 +146,8 @@ class PlayerDB(TypedObject):
# this is the one-to-one link between the customized Player object and
# this profile model. It is required by django.
- user = models.ForeignKey(User, unique=True, db_index=True,
- help_text="The User object holds django-specific authentication for each Player. A unique User should be created and tied to each Player, the two should never be switched or changed around. The User will be deleted automatically when the Player is.")
+ #user = models.ForeignKey(User, unique=True, db_index=True,
+ # help_text="The User object holds django-specific authentication for each Player. A unique User should be created and tied to each Player, the two should never be switched or changed around. The User will be deleted automatically when the Player is.")
# store a connected flag here too, not just in sessionhandler.
# This makes it easier to track from various out-of-process locations
db_is_connected = models.BooleanField(default=False, verbose_name="is_connected", help_text="If player is connected to game or not")
@@ -254,17 +255,19 @@ class PlayerDB(TypedObject):
#@property
def __name_get(self):
"Getter. Allows for value = self.name"
- name = get_prop_cache(self, "_name")
- if not name:
- name = _GA(self,"user").username
- set_prop_cache(self, "_name", name)
- return name
+ return self.username
+ #name = get_prop_cache(self, "_name")
+ #if not name:
+ # name = _GA(self,"user").username
+ # set_prop_cache(self, "_name", name)
+ #return name
#@name.setter
def __name_set(self, value):
"Setter. Allows for player.name = newname"
- _GA(self, "user").username = value
- _GA(self, "user").save()
- set_prop_cache(self, "_name", value)
+ self.username = value
+ #_GA(self, "user").username = value
+ #_GA(self, "user").save()
+ #set_prop_cache(self, "_name", value)
#@name.deleter
def __name_del(self):
"Deleter. Allows for del self.name"
@@ -275,11 +278,12 @@ class PlayerDB(TypedObject):
#@property
def __uid_get(self):
"Getter. Retrieves the user id"
- uid = get_prop_cache(self, "_uid")
- if not uid:
- uid = _GA(self, "user").id
- set_prop_cache(self, "_uid", uid)
- return uid
+ return self.id
+ #uid = get_prop_cache(self, "_uid")
+ #if not uid:
+ # uid = _GA(self, "user").id
+ # set_prop_cache(self, "_uid", uid)
+ #return uid
def __uid_set(self, value):
raise Exception("User id cannot be set!")
def __uid_del(self):
@@ -287,14 +291,15 @@ class PlayerDB(TypedObject):
uid = property(__uid_get, __uid_set, __uid_del)
#@property
- def __is_superuser_get(self):
- "Superusers have all permissions."
- is_suser = get_prop_cache(self, "_is_superuser")
- if is_suser == None:
- is_suser = _GA(self, "user").is_superuser
- set_prop_cache(self, "_is_superuser", is_suser)
- return is_suser
- is_superuser = property(__is_superuser_get)
+ #def __is_superuser_get(self):
+ # "Superusers have all permissions."
+ # return self.db_is_superuser
+ # #is_suser = get_prop_cache(self, "_is_superuser")
+ # #if is_suser == None:
+ # # is_suser = _GA(self, "user").is_superuser
+ # # set_prop_cache(self, "_is_superuser", is_suser)
+ # #return is_suser
+ #is_superuser = property(__is_superuser_get)
#
# PlayerDB class access methods
@@ -516,16 +521,12 @@ class PlayerDB(TypedObject):
self.unpuppet_object(session.sessid)
session.sessionhandler.disconnect(session, reason=_("Player being deleted."))
- try:
- if _GA(self, "user"):
- _GA(_GA(self, "user"), "delete")()
- except AssertionError:
- pass
- try:
- super(PlayerDB, self).delete(*args, **kwargs)
- except AssertionError:
- # this means deleting the user already cleared out the Player object.
- pass
+ #try:
+ # if _GA(self, "user"):
+ # _GA(_GA(self, "user"), "delete")()
+ #except AssertionError:
+ # pass
+ super(PlayerDB, self).delete(*args, **kwargs)
def execute_cmd(self, raw_string, sessid=None):
"""
@@ -573,3 +574,6 @@ class PlayerDB(TypedObject):
except:
pass
return matches
+
+class PlayerDBtmp(AbstractUser):
+ pass
diff --git a/src/server/initial_setup.py b/src/server/initial_setup.py
index dc0326fe7..f93da77d5 100644
--- a/src/server/initial_setup.py
+++ b/src/server/initial_setup.py
@@ -7,13 +7,15 @@ Everything starts at handle_setup()
"""
import django
-from django.contrib.auth.models import User
from django.core import management
from django.conf import settings
+from django.core.management import call_command
+from django.contrib.auth import get_user_model
from src.server.models import ServerConfig
from src.help.models import HelpEntry
from src.utils import create
+
from django.utils.translation import ugettext as _
def create_config_values():
@@ -25,9 +27,18 @@ def create_config_values():
def get_god_user():
"""
- Returns the initially created 'god' User object.
+ Creates the god user.
"""
- return User.objects.get(id=1)
+ PlayerDB = get_user_model()
+ try:
+ god_user = PlayerDB.objects.get(id=1)
+ except PlayerDB.DoesNotExist:
+ txt = "\n\nNo superuser exists yet. The superuser is the 'owner' account on the"
+ txt += "\nEvennia server; a good safety fallback. Create a new superuser using the command"
+ txt += "\n\n python manage.py createsuperuser"
+ txt += "\n\nFollow the prompts, then restart the server."
+ raise Exception(txt)
+ return god_user
def create_objects():
"""
diff --git a/src/settings_default.py b/src/settings_default.py
index 068709af8..90d050948 100644
--- a/src/settings_default.py
+++ b/src/settings_default.py
@@ -484,11 +484,12 @@ INSTALLED_APPS = (
'src.comms',
'src.help',
'src.scripts',
- 'src.web.news',
+ #'src.web.news',
'src.web.website',)
# The user profile extends the User object with more functionality;
# This should usually not be changed.
-AUTH_PROFILE_MODULE = "players.PlayerDB"
+AUTH_USER_MODEL = "players.PlayerDB"
+#AUTH_PROFILE_MODULE = "players.PlayerDB"
# Use a custom test runner that just tests Evennia-specific apps.
TEST_RUNNER = 'src.utils.test_utils.EvenniaTestSuiteRunner'
diff --git a/src/web/news/models.py b/src/web/news/models.py
index 02819644f..9ea8f5495 100755
--- a/src/web/news/models.py
+++ b/src/web/news/models.py
@@ -1,7 +1,7 @@
#
# This module implements a simple news entry system
-# for the evennia website. One needs to use the
-# admin interface to add/edit/delete entries.
+# for the evennia website. One needs to use the
+# admin interface to add/edit/delete entries.
#
from django.db import models
@@ -13,8 +13,8 @@ class NewsTopic(models.Model):
"""
name = models.CharField(max_length=75, unique=True)
description = models.TextField(blank=True)
- icon = models.ImageField(upload_to='newstopic_icons',
- default='newstopic_icons/default.png',
+ icon = models.ImageField(upload_to='newstopic_icons',
+ default='newstopic_icons/default.png',
blank=True, help_text="Image for the news topic.")
def __str__(self):
@@ -35,7 +35,7 @@ class NewsEntry(models.Model):
body = models.TextField()
topic = models.ForeignKey(NewsTopic, related_name='newstopic')
date_posted = models.DateTimeField(auto_now_add=True)
-
+
def __str__(self):
return self.title