From 5d91c1e20ec741334a83049d00bfb8c6dbc0223b Mon Sep 17 00:00:00 2001 From: Patrick Taylor Date: Wed, 30 Jan 2013 23:45:48 -0400 Subject: [PATCH 1/5] Backwards compatible Django 1.5 Custom User model support --- djangoratings/models.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/djangoratings/models.py b/djangoratings/models.py index 6e78d29..1003813 100644 --- a/djangoratings/models.py +++ b/djangoratings/models.py @@ -3,7 +3,14 @@ from django.db import models from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes import generic -from django.contrib.auth.models import User + +# support for custom User models in Django 1.5+ +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() try: from django.utils.timezone import now From 5c1296ebcf68e5aadd61f6b331bfd8397c1b6eb6 Mon Sep 17 00:00:00 2001 From: Patrick Taylor Date: Wed, 30 Jan 2013 23:47:55 -0400 Subject: [PATCH 2/5] Add custom User model support to tests.py --- djangoratings/tests.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/djangoratings/tests.py b/djangoratings/tests.py index a748cb9..f66f443 100644 --- a/djangoratings/tests.py +++ b/djangoratings/tests.py @@ -2,7 +2,6 @@ import random from django.db import models -from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from django.conf import settings @@ -10,6 +9,15 @@ from models import Vote, SimilarUser, IgnoredObject from fields import AnonymousRatingField, RatingField +# support for custom User models in Django 1.5+ +try: + from django.contrib.auth import get_user_model +except ImportError: # django < 1.5 + from django.contrib.auth.models import User +else: + User = get_user_model() + + settings.RATINGS_VOTES_PER_IP = 1 class RatingTestModel(models.Model): From ecde6814dbc14ac949ef5a08bc5c9c64dca0be17 Mon Sep 17 00:00:00 2001 From: Deepak Prakash Date: Sun, 9 Jun 2013 02:07:54 +0530 Subject: [PATCH 3/5] Backward compatible functions to get the User model name and User model Can be used both in case of Django <= 1.4 and >= 1.5 --- djangoratings/compat.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 djangoratings/compat.py diff --git a/djangoratings/compat.py b/djangoratings/compat.py new file mode 100644 index 0000000..cfc0a8c --- /dev/null +++ b/djangoratings/compat.py @@ -0,0 +1,15 @@ +from django.conf import settings + + +# Django 1.5 compatibility utilities, providing support for custom User models. +# Since get_user_model() causes a circular import if called when app models are +# being loaded, the user_model_label should be used when possible, with calls +# to get_user_model deferred to execution time + +user_model_label = getattr(settings, 'AUTH_USER_MODEL', 'auth.User') + +try: + from django.contrib.auth import get_user_model +except ImportError: + from django.contrib.auth.models import User + get_user_model = lambda: User From 885e93a0263ebf752b0bafbfbe5d9c2f4102bfb8 Mon Sep 17 00:00:00 2001 From: Deepak Prakash Date: Sun, 9 Jun 2013 02:08:34 +0530 Subject: [PATCH 4/5] Fixed migrations to run from scratch on projects with a custom User model Backward compatible. Will work for older versions as well. --- djangoratings/migrations/0001_initial.py | 7 +++++-- .../migrations/0002_add_mean_and_stddev.py | 9 ++++++--- .../migrations/0003_add_correlations.py | 9 ++++++--- .../migrations/0004_rethink_recommendations.py | 16 +++++++++------- djangoratings/migrations/0005_add_exclusions.py | 17 ++++++++++------- djangoratings/migrations/0006_add_cookies.py | 14 ++++++++------ 6 files changed, 44 insertions(+), 28 deletions(-) diff --git a/djangoratings/migrations/0001_initial.py b/djangoratings/migrations/0001_initial.py index 9eda4fe..7c883c0 100644 --- a/djangoratings/migrations/0001_initial.py +++ b/djangoratings/migrations/0001_initial.py @@ -3,6 +3,9 @@ from django.db import models from djangoratings.models import * +from djangoratings.compat import user_model_label + + class Migration: def forwards(self, orm): @@ -69,7 +72,7 @@ def backwards(self, orm): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { + user_model_label: { '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'}), @@ -110,7 +113,7 @@ def backwards(self, orm): 'key': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), 'score': ('django.db.models.fields.IntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'votes'", 'null': 'True', 'to': "orm['auth.User']"}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'votes'", 'null': 'True', 'to': "orm['%s']" % user_model_label}) } } diff --git a/djangoratings/migrations/0002_add_mean_and_stddev.py b/djangoratings/migrations/0002_add_mean_and_stddev.py index deb469f..f8052e3 100644 --- a/djangoratings/migrations/0002_add_mean_and_stddev.py +++ b/djangoratings/migrations/0002_add_mean_and_stddev.py @@ -4,6 +4,9 @@ from south.v2 import SchemaMigration from django.db import models +from djangoratings.compat import user_model_label + + class Migration(SchemaMigration): def forwards(self, orm): @@ -38,8 +41,8 @@ def backwards(self, orm): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': user_model_label.split('.')[-1]}, '_battlenet_profiles': ('django.db.models.fields.TextField', [], {'null': 'True', 'db_column': "'battlenet_profiles'", 'blank': 'True'}), 'avatar': ('django.db.models.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), 'bio': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), @@ -92,7 +95,7 @@ def backwards(self, orm): 'key': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), 'score': ('django.db.models.fields.IntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'votes'", 'null': 'True', 'to': "orm['auth.User']"}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'votes'", 'null': 'True', 'to': "orm['%s']" % user_model_label}) } } diff --git a/djangoratings/migrations/0003_add_correlations.py b/djangoratings/migrations/0003_add_correlations.py index d2b03de..c049bdf 100644 --- a/djangoratings/migrations/0003_add_correlations.py +++ b/djangoratings/migrations/0003_add_correlations.py @@ -4,6 +4,9 @@ from south.v2 import SchemaMigration from django.db import models +from djangoratings.compat import user_model_label + + class Migration(SchemaMigration): def forwards(self, orm): @@ -40,8 +43,8 @@ def backwards(self, orm): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': user_model_label.split('.')[-1]}, '_battlenet_profiles': ('django.db.models.fields.TextField', [], {'null': 'True', 'db_column': "'battlenet_profiles'", 'blank': 'True'}), 'avatar': ('django.db.models.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), 'bio': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), @@ -103,7 +106,7 @@ def backwards(self, orm): 'key': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), 'score': ('django.db.models.fields.IntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'votes'", 'null': 'True', 'to': "orm['auth.User']"}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'votes'", 'null': 'True', 'to': "orm['%s']" % user_model_label}) } } diff --git a/djangoratings/migrations/0004_rethink_recommendations.py b/djangoratings/migrations/0004_rethink_recommendations.py index 4047b4d..6f226ea 100644 --- a/djangoratings/migrations/0004_rethink_recommendations.py +++ b/djangoratings/migrations/0004_rethink_recommendations.py @@ -4,6 +4,8 @@ from south.v2 import SchemaMigration from django.db import models +from djangoratings.compat import user_model_label + class Migration(SchemaMigration): def forwards(self, orm): @@ -13,11 +15,11 @@ def forwards(self, orm): # Adding model 'SimilarUser' db.create_table('djangoratings_similaruser', ( - ('to_user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='similar_users_from', to=orm['auth.User'])), + ('to_user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='similar_users_from', to=orm[user_model_label])), ('agrees', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)), ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('disagrees', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)), - ('from_user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='similar_users', to=orm['auth.User'])), + ('from_user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='similar_users', to=orm[user_model_label])), )) db.send_create_signal('djangoratings', ['SimilarUser']) @@ -65,8 +67,8 @@ def backwards(self, orm): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': user_model_label.split('.')[-1]}, '_battlenet_profiles': ('django.db.models.fields.TextField', [], {'null': 'True', 'db_column': "'battlenet_profiles'", 'blank': 'True'}), 'avatar': ('django.db.models.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), 'bio': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), @@ -111,9 +113,9 @@ def backwards(self, orm): 'Meta': {'unique_together': "(('from_user', 'to_user'),)", 'object_name': 'SimilarUser'}, 'agrees': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), 'disagrees': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), - 'from_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'similar_users'", 'to': "orm['auth.User']"}), + 'from_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'similar_users'", 'to': "orm['%s']" % user_model_label}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'to_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'similar_users_from'", 'to': "orm['auth.User']"}) + 'to_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'similar_users_from'", 'to': "orm['%s']" % user_model_label}) }, 'djangoratings.vote': { 'Meta': {'unique_together': "(('content_type', 'object_id', 'key', 'user', 'ip_address'),)", 'object_name': 'Vote'}, @@ -125,7 +127,7 @@ def backwards(self, orm): 'key': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), 'score': ('django.db.models.fields.IntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'votes'", 'null': 'True', 'to': "orm['auth.User']"}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'votes'", 'null': 'True', 'to': "orm['%s']" % user_model_label}) } } diff --git a/djangoratings/migrations/0005_add_exclusions.py b/djangoratings/migrations/0005_add_exclusions.py index 5e27817..9a753f9 100644 --- a/djangoratings/migrations/0005_add_exclusions.py +++ b/djangoratings/migrations/0005_add_exclusions.py @@ -4,6 +4,9 @@ from south.v2 import SchemaMigration from django.db import models +from djangoratings.compat import user_model_label + + class Migration(SchemaMigration): def forwards(self, orm): @@ -13,7 +16,7 @@ def forwards(self, orm): ('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()), ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])), - ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])), + ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm[user_model_label])), )) db.send_create_signal('djangoratings', ['IgnoredObject']) @@ -44,8 +47,8 @@ def backwards(self, orm): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': user_model_label.split('.')[-1]}, '_battlenet_profiles': ('django.db.models.fields.TextField', [], {'null': 'True', 'db_column': "'battlenet_profiles'", 'blank': 'True'}), 'avatar': ('django.db.models.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), 'bio': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), @@ -82,7 +85,7 @@ def backwards(self, orm): 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_model_label}) }, 'djangoratings.score': { 'Meta': {'unique_together': "(('content_type', 'object_id', 'key'),)", 'object_name': 'Score'}, @@ -98,9 +101,9 @@ def backwards(self, orm): 'agrees': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), 'disagrees': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), 'exclude': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'from_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'similar_users'", 'to': "orm['auth.User']"}), + 'from_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'similar_users'", 'to': "orm['%s']" % user_model_label}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'to_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'similar_users_from'", 'to': "orm['auth.User']"}) + 'to_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'similar_users_from'", 'to': "orm['%s']" % user_model_label}) }, 'djangoratings.vote': { 'Meta': {'unique_together': "(('content_type', 'object_id', 'key', 'user', 'ip_address'),)", 'object_name': 'Vote'}, @@ -112,7 +115,7 @@ def backwards(self, orm): 'key': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), 'score': ('django.db.models.fields.IntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'votes'", 'null': 'True', 'to': "orm['auth.User']"}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'votes'", 'null': 'True', 'to': "orm['%s']" % user_model_label}) } } diff --git a/djangoratings/migrations/0006_add_cookies.py b/djangoratings/migrations/0006_add_cookies.py index 4e9e99e..cb81a64 100644 --- a/djangoratings/migrations/0006_add_cookies.py +++ b/djangoratings/migrations/0006_add_cookies.py @@ -4,6 +4,8 @@ from south.v2 import SchemaMigration from django.db import models +from djangoratings.compat import user_model_label + class Migration(SchemaMigration): def forwards(self, orm): @@ -44,8 +46,8 @@ def backwards(self, orm): 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, + user_model_label: { + 'Meta': {'object_name': user_model_label.split('.')[-1]}, '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'}), @@ -72,7 +74,7 @@ def backwards(self, orm): 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['%s']" % user_model_label}) }, 'djangoratings.score': { 'Meta': {'unique_together': "(('content_type', 'object_id', 'key'),)", 'object_name': 'Score'}, @@ -88,9 +90,9 @@ def backwards(self, orm): 'agrees': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), 'disagrees': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), 'exclude': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'from_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'similar_users'", 'to': "orm['auth.User']"}), + 'from_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'similar_users'", 'to': "orm['%s']" % user_model_label}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'to_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'similar_users_from'", 'to': "orm['auth.User']"}) + 'to_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'similar_users_from'", 'to': "orm['%s']" % user_model_label}) }, 'djangoratings.vote': { 'Meta': {'unique_together': "(('content_type', 'object_id', 'key', 'user', 'ip_address', 'cookie'),)", 'object_name': 'Vote'}, @@ -103,7 +105,7 @@ def backwards(self, orm): 'key': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), 'score': ('django.db.models.fields.IntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'votes'", 'null': 'True', 'to': "orm['auth.User']"}) + 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'votes'", 'null': 'True', 'to': "orm['%s']" % user_model_label}) } } From 6622ee58ade066589968ba23588f82698963e0fa Mon Sep 17 00:00:00 2001 From: Deepak Prakash Date: Thu, 13 Jun 2013 17:14:33 +0530 Subject: [PATCH 5/5] Use the custom user model label instead of the user model class to define ForeignKey relationships This solves some issues in Celery where there were Import errors - most probably due to circular dependencies. --- djangoratings/models.py | 8 ++------ djangoratings/tests.py | 9 ++------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/djangoratings/models.py b/djangoratings/models.py index 1003813..b590329 100644 --- a/djangoratings/models.py +++ b/djangoratings/models.py @@ -5,12 +5,8 @@ from django.contrib.contenttypes import generic # support for custom User models in Django 1.5+ -try: - from django.contrib.auth import get_user_model -except ImportError: # django < 1.5 - from django.contrib.auth.models import User -else: - User = get_user_model() +from djangoratings.compat import user_model_label +User = user_model_label try: from django.utils.timezone import now diff --git a/djangoratings/tests.py b/djangoratings/tests.py index f66f443..5c8c375 100644 --- a/djangoratings/tests.py +++ b/djangoratings/tests.py @@ -10,13 +10,8 @@ from fields import AnonymousRatingField, RatingField # support for custom User models in Django 1.5+ -try: - from django.contrib.auth import get_user_model -except ImportError: # django < 1.5 - from django.contrib.auth.models import User -else: - User = get_user_model() - +from djangoratings.compat import user_model_label +User = user_model_label settings.RATINGS_VOTES_PER_IP = 1