2010-02-13 5 views
2

J'ai un modèle de promotion qui contient des codes de promotion et une clé étrangère pour une classe de modèle d'achat.Django, génération de champs uniques

Voici le modèle:

class Promotion(models.Model): 
purchase = models.ForeignKey('Purchase') 
promotion_code = models.CharField(max_length=20) 
def promotion_code_generate(self): #returns a string based promotion code with 7 length 
    from django.conf import settings 
    import random, string 
    return ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(7)) 
class Meta: 
    unique_together = (("purchase", "promotion_code"),) 

Maintenant, je veux que mon champ PROMOTION_CODE être unique pour chaque achat et que j'ai ajouté unique_together = (("purchase", "promotion_code"),) à la classe méta. Cela fonctionne très bien lors de la saisie d'une nouvelle entrée via le panneau d'administration, car les codes promotionnels sont vides et je dois les entrer à la main.

Cependant, je souhaite que cela soit unique afin que, lors d'un achat, le système prenne cette instance de modèle Purcase et génère automatiquement cette instance de classe Promotion liée via le champ d'achat du modèle Promotion.

Pour cela, je besoin de deux choses:

1 - Je dois ma méthode de promotion_code_generate à vérifier les instances de modèle de promotion plus tôt et si le code actuellement généré n'existe pas dans le passé pour l'affaire, le retourner, si ce n'est pas en régénérant une nouvelle tentative jusqu'à ce qu'une chaîne de code de promotion non existante pour cet achat soit trouvée.

2- J'ai essayé attribuer un promotion_code_generation par défaut au champ PROMOTION_CODE cependant échoué:

promotion_code = models.CharField(max_length=20,default=self.promotion_code_generate()) 

Comment peut-on résoudre?

Répondre

3
import random 

@property 
def promotion_code_generate(self): 
    while 1: 
     prom_code = str(random.random())[2:] 
     try: 
      Promotion.objects.get(promotion_code=prom_code) 
     except: 
      return prom_code 

Définir comme @property, vous pouvez l'affecter au paramètre default.

+0

Semble intelligent, mais je reçois encore I "nom 'auto' est pas défini" une fois ne PROMOTION_CODE = models.CharField (max_length = 20, valeur par défaut = self.promotion_code_generate()) – Hellnar

+0

Ok, donc fais une méthode séparée, en dehors de la classe, je ne sais pas si des trucs méta interférent. Oh, quand vous faites cela, retirez le décorateur de la propriété. –

+0

Cela n'a rien à voir avec les métaclasses, mais simplement le fait que ceci est défini dans les déclarations de niveau classe, où 'self' n'existe pas. N'oubliez pas que 'self' n'est pas magique, c'est simplement la convention pour le premier paramètre pour les méthodes d'instance. Puisque la déclaration a lieu en dehors d'une méthode, il n'y a pas de 'self'. –

Questions connexes