Membership invitations and order emails #47
|
@ -148,21 +148,21 @@ class MemberAdmin(UserAdmin):
|
||||||
class WaitingListEntryAdmin(admin.ModelAdmin):
|
class WaitingListEntryAdmin(admin.ModelAdmin):
|
||||||
"""Admin for WaitingList model."""
|
"""Admin for WaitingList model."""
|
||||||
|
|
||||||
list_display = ("email", "has_user")
|
list_display = ("email", "member")
|
||||||
actions = ("create_user",)
|
actions = ("create_member",)
|
||||||
|
|
||||||
@admin.action(description="Create user account for entries")
|
@admin.action(description="Create member account for entries")
|
||||||
def create_user(self, request: HttpRequest, queryset: QuerySet[WaitingListEntry]) -> None:
|
def create_member(self, request: HttpRequest, queryset: QuerySet[WaitingListEntry]) -> None:
|
||||||
"""Create a user account for this entry.
|
"""Create a user account for this entry.
|
||||||
|
|
||||||
Note that actions can soon be made available from the edit page, too:
|
Note that actions can soon be made available from the edit page, too:
|
||||||
https://github.com/django/django/pull/16012
|
https://github.com/django/django/pull/16012
|
||||||
"""
|
"""
|
||||||
for entry in queryset:
|
for entry in queryset:
|
||||||
Member.objects.create_user(email=entry.email, username=slugify(entry.email), is_active=False)
|
member = Member.objects.create_user(email=entry.email, username=slugify(entry.email), is_active=False)
|
||||||
entry.has_user = True
|
entry.member = member
|
||||||
entry.save()
|
entry.save()
|
||||||
messages.info(
|
messages.info(
|
||||||
request,
|
request,
|
||||||
f"Added user for f{entry.email} - ensure they have a membership and send an invite email.",
|
f"Added user for {entry.email} - ensure they have a membership and send an invite email.",
|
||||||
)
|
)
|
||||||
|
|
|
@ -23,6 +23,7 @@ class InviteForm(SetPasswordForm):
|
||||||
Taken from the allauth Signup form - we should consider that data can be leaked here.
|
Taken from the allauth Signup form - we should consider that data can be leaked here.
|
||||||
"""
|
"""
|
||||||
value = self.cleaned_data["username"]
|
value = self.cleaned_data["username"]
|
||||||
|
# The allauth adapter ensures the username is unique.
|
||||||
return get_allauth_adapter().clean_username(value)
|
return get_allauth_adapter().clean_username(value)
|
||||||
|
|
||||||
def save(self) -> None:
|
def save(self) -> None:
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
# Generated by Django 5.1rc1 on 2024-08-11 21:27
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('membership', '0009_membership_referral_code'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='waitinglistentry',
|
|
||||||
name='has_user',
|
|
||||||
field=models.BooleanField(default=False, help_text='Once a user account is generated (use the admin action), this field will be marked.', verbose_name='has user'),
|
|
||||||
),
|
|
||||||
]
|
|
19
src/membership/migrations/0010_waitinglistentry_member.py
Normal file
19
src/membership/migrations/0010_waitinglistentry_member.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Generated by Django 5.1rc1 on 2024-08-14 08:05
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('membership', '0009_membership_referral_code'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='waitinglistentry',
|
||||||
|
name='member',
|
||||||
|
field=models.ForeignKey(help_text='Once a member account is generated (use the admin action), this field will be marked.', null=True, blank=True, on_delete=django.db.models.deletion.CASCADE, to='membership.member', verbose_name='has member'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -230,10 +230,13 @@ class WaitingListEntry(CreatedModifiedAbstract):
|
||||||
email = models.EmailField()
|
email = models.EmailField()
|
||||||
geography = models.CharField(verbose_name=_("geography"), blank=True, default="")
|
geography = models.CharField(verbose_name=_("geography"), blank=True, default="")
|
||||||
comment = models.TextField(blank=True)
|
comment = models.TextField(blank=True)
|
||||||
has_user = models.BooleanField(
|
member = models.ForeignKey(
|
||||||
benjaoming marked this conversation as resolved
Outdated
|
|||||||
default=False,
|
Member,
|
||||||
verbose_name=_("has user"),
|
null=True,
|
||||||
help_text=_("Once a user account is generated (use the admin action), this field will be marked."),
|
blank=True,
|
||||||
|
verbose_name=_("has member"),
|
||||||
|
help_text=_("Once a member account is generated (use the admin action), this field will be marked."),
|
||||||
|
on_delete=models.CASCADE,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
|
|
Loading…
Reference in a new issue
Why not have this as a
ForeignKey("Member")
?It's sensitive really. I suppose that once this turns into an application, we have to consider that people give out details that are 100% associated with their membership activity and if we want to keep that on record, we should make sure it's either very consistent with the functionality or write a privacy statement.
I was leaning a bit more towards deleting these records... but on that note, "right to be forgotten" is way easier to invoke when we ensure that we use FKs between personal data (or PII).
Changing.......