I am working on a Ticketing project where I want the admin to be to generate multiple unique numeric PINs that customers can purchase and can be validated on the app for event registration. I have researched and realised that this could also be done using bulk create but don't know how. Here is my Ticket Model
class Ticket(models.Model):
name =models.CharField(max_length=50)
price = models.PositiveIntegerField()
pin = models.CharField(max_length=6)
def __str__(self):
return self.name
I want a situation where admin would be able to generate multiple PINs for a particular ticket with a click but don't know how to go about it so someone should please help with the best way of doing it.
CodePudding user response:
This is for comments but since my reputation doesn't reach 50 let me added this:
If I understand you, you want when user submitted the Ticket model that Ticket will generated the a random number automatically in the admin.
This can be done using Python module called Random or using Django modules called Django Signals
Django Signals
Django includes a “signal dispatcher” which helps decoupled applications get notified when actions occur elsewhere in the framework. In a nutshell, signals allow certain senders to notify a set of receivers that some action has taken place. They’re especially useful when many pieces of code may be interested in the same events.
Python module Random
This module implements pseudo-random number generators for various distributions.
For integers, there is uniform selection from a range. For sequences, there is uniform selection of a random element, a function to generate a random permutation of a list in-place, and a function for random sampling without replacement.
CodePudding user response:
You should create another model TicketPIN
which has a ForeignKey
relation to Ticket
model:
from random import randint
from django.db import models
def generate_pin():
return ''.join(str(randint(0, 9)) for _ in range(6))
class TicketPIN(models.Model):
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
value = models.CharField(max_length=6, default=generate_pin, blank=True)
class Meta:
unique_together = ["ticket", "value"]
def __str__(self):
return f"{self.ticket} | {self.value}"
You won't need the pin field inside the Ticket
model.
Next, you should create a view that only superuser can access:
from django.http import JsonResponse
from .models import Ticket, TicketPIN
def generate_pins_for_ticket(request, ticket_id):
if request.user.is_superuser:
ticket = Ticket.objects.get(id=ticket_id)
for _ in range(20):
TicketPIN.objects.create(ticket=ticket)
return JsonResponse({"message": f"Created 20 PINs successfully for {ticket} ticket."})
return JsonResponse({"error": "Not Authorized"})
And in urls.py
:
from django.urls import path
from .views import generate_pins_for_ticket
urlpatterns = [
path("generate-pins/<int:ticket_id>", generate_pins_for_ticket),
]
Let's say the admin created a ticket that has id=1
, when the admin is logged out, any user that visits /generate-pins/1
will see the response {"error": "Not Authorized"}
. Only if the admin is logged in and he visits /generate-pins/1
will generate 20 PINs. you can modify the view to accept any number to generate and create a form so it's admin-friendly.