Added option to bulk create vouchers via the WebUI.

Closes #9
This commit is contained in:
Johannes Erwerle 2026-10-18 15:04:00 +02:00
parent f3d152b454
commit baea657d1a
5 changed files with 79 additions and 11 deletions

View file

@ -1,7 +1,50 @@
from django.contrib import admin from django.contrib import admin
from django.urls import path, reverse_lazy
from django.views.generic import FormView
from django import forms
from .models import BorgRepository, Voucher from .models import BorgRepository, Voucher
class VoucherBulkCreateForm(forms.Form):
prefix = forms.CharField(label="Voucher prefix")
amount = forms.IntegerField(label="Amount")
class VoucherBulkCreateView(FormView):
form_class = VoucherBulkCreateForm
template_name = "admin/bulk_generate.html"
admin_site_context = None
success_url = reverse_lazy("admin:webui_voucher_changelist")
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# inject the admin site context so that the navbar and other things work as intended
context.update(self.admin_site_context.each_context(self.request))
return context
def form_valid(self, form):
Voucher.bulk_generate(form.cleaned_data["prefix"], form.cleaned_data["amount"])
return super().form_valid(form)
@admin.register(Voucher)
class VoucherAdmin(admin.ModelAdmin):
change_list_template = "admin/voucher_change_list.html"
def get_urls(self):
urls = super().get_urls()
my_urls = [
path(
"bulk_generate/",
self.admin_site.admin_view(
VoucherBulkCreateView.as_view(admin_site_context=self.admin_site)
),
name="voucher_bulk_generate",
)
]
return my_urls + urls
# Register your models here. # Register your models here.
admin.site.register(BorgRepository) admin.site.register(BorgRepository)
admin.site.register(Voucher)

View file

@ -11,14 +11,7 @@ class Command(BaseCommand):
parser.add_argument("amount", type=int) parser.add_argument("amount", type=int)
def handle(self, *args, **options): def handle(self, *args, **options):
unabmigous_characters = "abcdefghijkmnopqrstuvwxyzACDEFHJKLMNPQRTUVWXY1234679" vouchers = Voucher.bulk_generate(options["prefix"], options["amount"])
vouchers = set()
while len(vouchers) < options["amount"]:
random_part = "".join(choices(unabmigous_characters, k=5))
vouchers.add(f"{options['prefix']}-{random_part}")
Voucher.objects.bulk_create(Voucher(code=v) for v in vouchers)
header = r"""\begin{document} header = r"""\begin{document}
\begin{center} \begin{center}

View file

@ -1,11 +1,12 @@
from random import choices
from pathlib import Path
from django.db import models from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.validators import RegexValidator from django.core.validators import RegexValidator
from django.conf import settings from django.conf import settings
from pathlib import Path
import msgpack import msgpack
from .tasks import update_user from .tasks import update_user
@ -121,3 +122,20 @@ class Voucher(models.Model):
def __str__(self): def __str__(self):
return f"Voucher '{self.code}'" return f"Voucher '{self.code}'"
@classmethod
def bulk_generate(cls, prefix: str, amount: int) -> set[str]:
"""
Create `amount` vouchers starting with `prefix`.
Returns a set of the voucher codes as strings.
"""
unabmigous_characters = "abcdefghijkmnopqrstuvwxyzACDEFHJKLMNPQRTUVWXY1234679"
vouchers = set()
while len(vouchers) < amount:
random_part = "".join(choices(unabmigous_characters, k=5))
vouchers.add(f"{prefix}-{random_part}")
Voucher.objects.bulk_create(Voucher(code=v) for v in vouchers)
return vouchers

View file

@ -0,0 +1,8 @@
{% extends "admin/base_site.html" %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="submit">
</form>
{% endblock %}

View file

@ -0,0 +1,6 @@
{% extends "admin/change_list.html" %}
{% block object-tools-items %}
{{ block.super }}
<li><a href="{% url 'admin:voucher_bulk_generate' %}" class="addlink">Bulk Generate Vouchers</a></li>
{% endblock %}