Estoy buscando un buen ejemplo o consejo para resolver mi problema en Django y Python. Tengo un modelo simple como Cliente
class Customer(models.Model): customer_name = models.CharField(max_length=500) CUSTOMER_CHOICES = [ ('pc', 'Private Customer'), ('bc', 'Business Customer'), ] customer_type = models.CharField(max_length=2, choices=CUSTOMER_CHOICES) customer_number = models.IntegerField(blank=True)Para todos los clientes, quiero crear (y mostrar en la página) un "Número de cliente" específico basado en el tipo de cliente y un número decimal. Creo que podría almacenar este valor en la tabla Cliente (algo parecido a esto):
|id|customer_name|customer_type|customer_number| |1 |Private 1 |pc |1 | |2 |Private 2 |pc |2 | |3 |Business 1 |bc |1 | |4 |Private 3 |pc |3 | |5 |Business 2 |bc |2 |Por supuesto, cuando modifique el nombre del cliente u otro valor (excepto el tipo de cliente y el número de cliente), no quiero actualizar este número.
Creo que el siguiente código no funcionará (esto es solo un ejemplo como se pensó al principio), porque no sé cómo funcionará el código cuando tenga dos sesiones diferentes y presione el botón Guardar al mismo tiempo. No sé si este código manejará correctamente un nuevo objeto, cuando eliminamos anteriormente, por ejemplo, la segunda fila, luego querremos agregar "nuevo cliente privado".
código editado:
def save(self, *args, **kwargs): # Get last object by customer type last_obj = Customer.objects.all().filter(customer_type=self.customer_type).last() # Checking if we had any entries by customer type # if not, this element must be first on the list # next, if new val is None we need to add 1 to the counter print(last_obj.customer_number) if last_obj is None: self.customer_number = 1 else: if self.customer_number is None: self.customer_number = last_obj.customer_number + 1 super(Customer, self).save(*args, **kwargs)¿Django tiene alguna herramienta para hacer esto realmente agradable?
Django no tiene una sola herramienta específica para lograr su resultado. Aquí hay dos opciones.
1. Método Save() Este es básicamente su enfoque. Pero debe combinarse con el UniqueConstraint.condition ( docs ) de Django para asegurarse de que el campo número_cliente sea único para cada tipo de cliente. Las restricciones del modelo se pueden establecer como una meta opción .
class Customer(models.Model): customer_name = models.CharField(max_length=500) CUSTOMER_CHOICES = [ ('pc', 'Private Customer'), ('bc', 'Business Customer'), ] customer_type = models.CharField(max_length=2, choices=CUSTOMER_CHOICES) class Meta: constraints = [ models.UniqueConstrained(fields=['customer_number'], condition=Q(customer_type='pc'), name='unique_pc_customer'), models.UniqueConstrained(fields=['customer_number'], condition=Q(customer_type='bc'), name='unique_bc_customer'), ] Si se viola la restricción, se genera un IntegrityError . Puede manejar el error en el método save() de su modelo.
def save(): try: #Set your customer_number except IntegrityError: #Handle the error as you wish2. Modelos separados Puede definir dos modelos adicionales, uno para pc y otro para bc. Esos modelos luego se relacionarían uno a uno con su modelo de Cliente. La identificación de su instancia de modelo de PC y la instancia de modelo bc sería su número de cliente.