david / django-invitation

Built on top of django-registration, it restricts registration to a given number of invited person per active user (strategy introduced by GMail to involve 2.0 users).

Clone this repository (size: 60.6 KB): HTTPS / SSH
$ hg clone http://code.welldev.org/django-invitation
commit 22: 8d2a11dc6129
parent 21: b2977a099938
branch: default
Added InvitationUser model to support explicit per-user invitations_remaining. See issue 4: http://bitbucket.org/david/django-invitation/issue/4/support-user-specific-number-of
David Montgomery / davidlmontgomery
14 months ago

Changed (Δ2.5 KB):

raw changeset »

invitation/admin.py (5 lines added, 1 lines removed)

invitation/models.py (29 lines added, 2 lines removed)

invitation/tests.py (25 lines added, 1 lines removed)

Up to file-list invitation/admin.py:

1
1
from django.contrib import admin
2
from invitation.models import InvitationKey
2
from invitation.models import InvitationKey, InvitationUser
3
3
4
4
class InvitationKeyAdmin(admin.ModelAdmin):
5
5
    list_display = ('__unicode__', 'from_user', 'date_invited', 'key_expired')
6
6
7
class InvitationUserAdmin(admin.ModelAdmin):
8
    list_display = ('inviter', 'invitations_remaining')
9
7
10
admin.site.register(InvitationKey, InvitationKeyAdmin)
11
admin.site.register(InvitationUser, InvitationUserAdmin)

Up to file-list invitation/models.py:

@@ -52,8 +52,7 @@ class InvitationKeyManager(models.Manage
52
52
        """
53
53
        Returns the number of remaining invitations for a given ``User``.
54
54
        """
55
        inviteds_count = self.filter(from_user=user).count()
56
        return settings.INVITATIONS_PER_USER - inviteds_count
55
        return InvitationUser.objects.get(inviter=user).invitations_remaining
57
56
58
57
    def delete_expired_keys(self):
59
58
        for key in self.all():
@@ -124,3 +123,31 @@ class InvitationKey(models.Model):
124
123
        send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [email])
125
124
126
125
        
126
class InvitationUser(models.Model):
127
    inviter = models.ForeignKey(User, unique=True)
128
    invitations_remaining = models.IntegerField()
129
130
    def __unicode__(self):
131
        return u"InvitationUser for %s" % self.inviter.username
132
133
    
134
def user_post_save(sender, instance, created, **kwargs):
135
    """Create InvitationUser for user when User is created."""
136
    if created:
137
        invitation_user = InvitationUser()
138
        invitation_user.inviter = instance
139
        invitation_user.invitations_remaining = settings.INVITATIONS_PER_USER
140
        invitation_user.save()
141
142
models.signals.post_save.connect(user_post_save, sender=User)
143
144
def invitation_key_post_save(sender, instance, created, **kwargs):
145
    """Decrement invitations_remaining when InvitationKey is created."""
146
    if created:
147
        invitation_user = InvitationUser.objects.get(inviter=instance.from_user)
148
        remaining = invitation_user.invitations_remaining
149
        invitation_user.invitations_remaining = remaining-1
150
        invitation_user.save()
151
152
models.signals.post_save.connect(invitation_key_post_save, sender=InvitationKey)
153

Up to file-list invitation/tests.py:

@@ -27,7 +27,7 @@ from django.core.urlresolvers import rev
27
27
from django.test import TestCase
28
28
29
29
from invitation import forms
30
from invitation.models import InvitationKey
30
from invitation.models import InvitationKey, InvitationUser
31
31
32
32
class InvitationTestCase(TestCase):
33
33
    """
@@ -97,8 +97,32 @@ class InvitationModelTests(InvitationTes
97
97
        """
98
98
        management.call_command('cleanupinvitation')
99
99
        self.assertEqual(InvitationKey.objects.count(), 1)
100
        
101
    def test_invitations_remaining(self):
102
        """Test InvitationUser calculates remaining invitations properly."""
103
        remaining_invites = InvitationKey.objects.remaining_invitations_for_user
100
104
105
        # New user starts with settings.INVITATIONS_PER_USER
106
        user = User.objects.create_user(username='newbie',
107
                                        password='secret',
108
                                        email='newbie@example.com')
109
        self.assertEqual(remaining_invites(user), settings.INVITATIONS_PER_USER)
101
110
111
        # After using some, amount remaining is decreased
112
        used = InvitationKey.objects.filter(from_user=self.sample_user).count()
113
        expected_remaining = settings.INVITATIONS_PER_USER - used
114
        remaining = remaining_invites(self.sample_user)
115
        self.assertEqual(remaining, expected_remaining)
116
        
117
        # Using Invitationuser via Admin, remaining can be increased
118
        invitation_user = InvitationUser.objects.get(inviter=self.sample_user)
119
        new_remaining = 2*settings.INVITATIONS_PER_USER + 1
120
        invitation_user.invitations_remaining = new_remaining
121
        invitation_user.save()
122
        remaining = remaining_invites(self.sample_user)
123
        self.assertEqual(remaining, new_remaining)
124
125
        
102
126
class InvitationFormTests(InvitationTestCase):
103
127
    """
104
128
    Tests for the forms and custom validation logic included in