views:

47

answers:

1

Hello, I have a Promotion model that contains a promotion codes and a foreignkey to a purchase model Class.

Here is the model:

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"),)

Now I want my promotion_code field to be unique for each purchase and for that I have added unique_together = (("purchase", "promotion_code"),) to the Class meta. It works fine while entering a new entry via admin panel as promotion code fiels are blank and I have to enter these by hand.

However I want to make this unique so that when a purchase is done, system should take that Purcase model instance and auto generate this Promotion class instance that is bound via the purchase field of Promotion model.

For this I need two things:

1 - I need my promotion_code_generate method to be checking the earlier Promotion model instances and if the currently generated code doesn't exist in the past for the deal, returning it, if not regenerating one again reattempting until a non-existing promotion code string for that purchase is found.

2- I have tried assign a default promotion_code_generation to the promotion_code field however failed:

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

How can these be solved ?

+1  A: 
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

Defining it as @property, you can assign it to the default parameter.

Lakshman Prasad
Seems clever but I still get "name 'self' is not defined"once I do promotion_code = models.CharField(max_length=20,default=self.promotion_code_generate())
Hellnar
Ok, So make it a seperate method, outside of the class, I dont know if some meta class stuff is interfering.Oh, when you make this, remove the property decorator.
Lakshman Prasad
@becomingGuru: It's nothing to do with metaclasses, but simply the fact that this is being defined in the class-level declarations, where `self` does not exist. Don't forget, `self` isn't magic, it's simply the convention for the first parameter to instance methods. Since the declaration takes place outside a method, there's no `self`.
Daniel Roseman
Daniel: Well, "It was obvious that this method needed to be placed within the class, because it has self as the first parameter;" is what I thought.
Lakshman Prasad