Repository: dotkom/onlineweb4

Issue:
EmailInline showing a user's emails in admin
Since emails are now managed with a model of its own, we need to put an inline in the admin panel for it.



Discussion:
Is this in the "Brukerprofiler"-admin page like when adding a user? 

Yes. The email field that is currently shown in the admin for users isn't even used. It comes from the standard django model, which we aren't using any more.


Resolving patch:
diff --git a/apps/authentication/admin.py b/apps/authentication/admin.py
--- a/apps/authentication/admin.py
+++ b/apps/authentication/admin.py
@@ -3,26 +3,34 @@
 from django.contrib import admin
 from django.utils.translation import ugettext as _
 
-from apps.authentication.models import OnlineUser, AllowedUsername
+from apps.authentication.models import AllowedUsername, Email, OnlineUser
+
+
+class EmailInline(admin.TabularInline):
+    model = Email
+    extra = 1 
+
 
 class OnlineUserAdmin(admin.ModelAdmin):
     model = OnlineUser
+    inlines = (EmailInline,)
     list_display = ['username', 'first_name', 'last_name', 'field_of_study', 'is_member',]
     list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups')
     fieldsets = (
         (None, {'fields': ('username', 'password')}),
-        (_(u'Personal info'), {'fields': ('first_name', 'last_name', 'email', 'phone_number', )}),
+        (_(u'Personlig info'), {'fields': ('first_name', 'last_name', 'phone_number', )}),
         (_(u'Studieinformasjon'), {'fields': ('ntnu_username', 'field_of_study', 'started_date', 'compiled',)}),
-        (_(u'Address'), {'fields': ('address', 'zip_code',)}), 
-        (_(u'Important dates'), {'fields': ('last_login', 'date_joined',)}),
-        (_(u'Other info'), { 'fields': ('infomail', 'mark_rules', 'rfid', 'nickname', 'website', 'image',) }),
-        (_(u'Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser',
+        (_(u'Adresse'), {'fields': ('address', 'zip_code',)}), 
+        (_(u'Viktige datoer'), {'fields': ('last_login', 'date_joined',)}),
+        (_(u'Annen info'), { 'fields': ('infomail', 'mark_rules', 'rfid', 'nickname', 'website', 'image',) }),
+        (_(u'Tilganger'), {'fields': ('is_active', 'is_staff', 'is_superuser',
                                        'groups', 'user_permissions')}),
     )
     filter_horizontal = ('groups', 'user_permissions',)
 
 admin.site.register(OnlineUser, OnlineUserAdmin)
 
+
 class AllowedUsernameAdmin(admin.ModelAdmin):
     model = AllowedUsername
     list_display = ('username', 'registered', 'expiration_date', 'note')
diff --git a/apps/authentication/migrations/0011_auto__add_unique_allowedusername_username__add_unique_onlineuser_ntnu_.py b/apps/authentication/migrations/0011_auto__add_unique_allowedusername_username__add_unique_onlineuser_ntnu_.py
new file mode 100644
--- /dev/null
+++ b/apps/authentication/migrations/0011_auto__add_unique_allowedusername_username__add_unique_onlineuser_ntnu_.py
@@ -0,0 +1,104 @@
+# -*- 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):
+        # Adding unique constraint on 'AllowedUsername', fields ['username']
+        db.create_unique(u'authentication_allowedusername', ['username'])
+
+        # Adding unique constraint on 'OnlineUser', fields ['ntnu_username']
+        db.create_unique(u'authentication_onlineuser', ['ntnu_username'])
+
+
+    def backwards(self, orm):
+        # Removing unique constraint on 'OnlineUser', fields ['ntnu_username']
+        db.delete_unique(u'authentication_onlineuser', ['ntnu_username'])
+
+        # Removing unique constraint on 'AllowedUsername', fields ['username']
+        db.delete_unique(u'authentication_allowedusername', ['username'])
+
+
+    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'authentication.allowedusername': {
+            'Meta': {'ordering': "(u'username',)", 'object_name': 'AllowedUsername'},
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'expiration_date': ('django.db.models.fields.DateField', [], {}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'note': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'registered': ('django.db.models.fields.DateField', [], {}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '10'})
+        },
+        u'authentication.email': {
+            'Meta': {'object_name': 'Email'},
+            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'primary': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'email_user'", 'to': u"orm['authentication.OnlineUser']"}),
+            'verified': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+        },
+        u'authentication.onlineuser': {
+            'Meta': {'ordering': "['first_name', 'last_name']", 'object_name': 'OnlineUser'},
+            'address': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+            'allergies': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'compiled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'field_of_study': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+            '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'}),
+            'image': ('django.db.models.fields.files.ImageField', [], {'default': "'/static/img/profile_default.png'", 'max_length': '200', 'null': 'True', 'blank': 'True'}),
+            'infomail': ('django.db.models.fields.BooleanField', [], {'default': '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'}),
+            'mark_rules': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'nickname': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'ntnu_username': ('django.db.models.fields.CharField', [], {'max_length': '10', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'phone_number': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}),
+            'rfid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'started_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2013, 11, 11, 0, 0)'}),
+            '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'}),
+            'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+            'zip_code': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'})
+        },
+        u'authentication.registertoken': {
+            'Meta': {'object_name': 'RegisterToken'},
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '254'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'token': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'register_user'", 'to': u"orm['authentication.OnlineUser']"})
+        },
+        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'})
+        }
+    }
+
+    complete_apps = ['authentication']
\ No newline at end of file
diff --git a/apps/authentication/models.py b/apps/authentication/models.py
--- a/apps/authentication/models.py
+++ b/apps/authentication/models.py
@@ -57,7 +57,7 @@ class OnlineUser(AbstractUser):
                               default=settings.DEFAULT_PROFILE_PICTURE_URL)
 
     # NTNU credentials
-    ntnu_username = models.CharField(_(u"NTNU-brukernavn"), max_length=10, blank=True, null=True)
+    ntnu_username = models.CharField(_(u"NTNU-brukernavn"), max_length=10, blank=True, null=True, unique=True)
 
     # TODO checkbox for forwarding of @online.ntnu.no mail
         
@@ -122,8 +122,8 @@ class Meta:
 class Email(models.Model):
     user = models.ForeignKey(OnlineUser, related_name="email_user")
     email = models.EmailField(_(u"epostadresse"), unique=True)
-    primary = models.BooleanField(_(u"aktiv"), default=False)
-    verified = models.BooleanField(_(u"verifisert"), default=False)
+    primary = models.BooleanField(_(u"primær"), default=False)
+    verified = models.BooleanField(_(u"verifisert"), default=False, editable=False)
 
     def __unicode__(self):
         return self.email
@@ -150,7 +150,7 @@ class AllowedUsername(models.Model):
     """
     Holds usernames that are considered valid members of Online and the time they expire.
     """
-    username = models.CharField(_(u"brukernavn"), max_length=10)
+    username = models.CharField(_(u"NTNU-brukernavn"), max_length=10, unique=True)
     registered = models.DateField(_(u"registrert"))
     note = models.CharField(_(u"notat"), max_length=100)
     description = models.TextField(_(u"beskrivelse"), blank=True, null=True)
@@ -164,7 +164,7 @@ def __unicode__(self):
         return self.username
 
     class Meta:
-        verbose_name = _(u"tillatt brukernavn")
-        verbose_name_plural = _(u"tillatte brukernavn")
+        verbose_name = _(u"medlemsregister")
+        verbose_name_plural = _(u"medlemsregister")
         ordering = (u"username",)
 


Test patch: