def test_deconstruct(self): f = ChoiceEnumField(enum_type=MyChoices) name, path, args_, kwargs_ = f.deconstruct() self.assertIsNone(name) self.assertEqual(path, 'shop.models.fields.ChoiceEnumField') self.assertListEqual(args_, []) self.assertDictEqual(kwargs_, {})
def test_deconstruct(): f = ChoiceEnumField(enum_type=MyChoices) name, path, args_, kwargs_ = f.deconstruct() assert name is None assert path == 'shop.models.fields.ChoiceEnumField' assert args_ == [] assert kwargs_ == {}
def test_to_python(self): f = ChoiceEnumField(enum_type=MyChoices) self.assertEqual(f.to_python(0), MyChoices.A) self.assertEqual(f.to_python('A'), MyChoices.A) self.assertEqual(f.to_python(1), MyChoices.B) with self.assertRaises(ValueError): f.to_python(None) with self.assertRaises(ValueError): f.to_python(3)
def test_to_python(): f = ChoiceEnumField(enum_type=MyChoices) assert f.to_python(0) == MyChoices.A assert f.to_python('A') == MyChoices.A assert f.to_python(1) == MyChoices.B with pytest.raises(ValueError): f.to_python(None) with pytest.raises(ValueError): f.to_python(3)
class Notification(models.Model): """ A task executed on receiving a signal. """ name = models.CharField( max_length=50, verbose_name=_("Name"), ) transition_target = models.CharField( max_length=50, verbose_name=_("Event"), ) notify = ChoiceEnumField( _("Whom to notify"), enum_type=Notify, ) recipient = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_("Recipient"), null=True, limit_choices_to={'is_staff': True}, ) mail_template = models.ForeignKey( EmailTemplate, on_delete=models.CASCADE, verbose_name=_("Template"), limit_choices_to=Q(language__isnull=True) | Q(language=''), ) class Meta: app_label = 'shop' verbose_name = _("Notification") verbose_name_plural = _("Notifications") ordering = ['transition_target', 'recipient_id'] def __str__(self): return self.name def get_recipient(self, order): if self.notify is Notify.RECIPIENT: return self.recipient.email if self.notify is Notify.CUSTOMER: return order.customer.email if self.notify is Notify.VENDOR: if hasattr(order, 'vendor'): return order.vendor.email return app_settings.SHOP_VENDOR_EMAIL
class BaseCustomer(with_metaclass(deferred.ForeignKeyBuilder, models.Model)): """ Base class for shop customers. Customer is a profile model that extends the django User model if a customer is authenticated. On checkout, a User object is created for anonymous customers also (with unusable password). """ user = models.OneToOneField( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, primary_key=True, ) recognized = ChoiceEnumField( _("Recognized as"), enum_type=CustomerState, help_text=_("Designates the state the customer is recognized as."), ) last_access = models.DateTimeField( _("Last accessed"), default=timezone.now, ) extra = JSONField( editable=False, verbose_name=_("Extra information about this customer"), ) objects = CustomerManager() class Meta: abstract = True def __str__(self): return self.get_username() def get_username(self): return self.user.get_username() def get_full_name(self): return self.user.get_full_name() @property def first_name(self): # pending deprecation: warnings.warn("Property first_name is deprecated and will be removed") return self.user.first_name @first_name.setter def first_name(self, value): # pending deprecation: warnings.warn("Property first_name is deprecated and will be removed") self.user.first_name = value @property def last_name(self): # pending deprecation: warnings.warn("Property last_name is deprecated and will be removed") return self.user.last_name @last_name.setter def last_name(self, value): # pending deprecation: warnings.warn("Property last_name is deprecated and will be removed") self.user.last_name = value @property def email(self): return self.user.email @email.setter def email(self, value): self.user.email = value @property def date_joined(self): return self.user.date_joined @property def last_login(self): return self.user.last_login @property def groups(self): return self.user.groups @property def is_anonymous(self): return self.recognized in (CustomerState.UNRECOGNIZED, CustomerState.GUEST) @property def is_authenticated(self): return self.recognized is CustomerState.REGISTERED @property def is_recognized(self): """ Return True if the customer is associated with a User account. Unrecognized customers have accessed the shop, but did not register an account nor declared themselves as guests. """ return self.recognized is not CustomerState.UNRECOGNIZED @property def is_guest(self): """ Return true if the customer isn't associated with valid User account, but declared himself as a guest, leaving their email address. """ return self.recognized is CustomerState.GUEST def recognize_as_guest(self, request=None, commit=True): """ Recognize the current customer as guest customer. """ if self.recognized != CustomerState.GUEST: self.recognized = CustomerState.GUEST if commit: self.save(update_fields=['recognized']) customer_recognized.send(sender=self.__class__, customer=self, request=request) @property def is_registered(self): """ Return true if the customer has registered himself. """ return self.recognized is CustomerState.REGISTERED def recognize_as_registered(self, request=None, commit=True): """ Recognize the current customer as registered customer. """ if self.recognized != CustomerState.REGISTERED: self.recognized = CustomerState.REGISTERED if commit: self.save(update_fields=['recognized']) customer_recognized.send(sender=self.__class__, customer=self, request=request) @property def is_visitor(self): """ Always False for instantiated Customer objects. """ return False @property def is_expired(self): """ Return True if the session of an unrecognized customer expired or is not decodable. Registered customers never expire. Guest customers only expire, if they failed fulfilling the purchase. """ is_expired = False if self.recognized is CustomerState.UNRECOGNIZED: try: session_key = CustomerManager.decode_session_key(self.user.username) is_expired = not SessionStore.exists(session_key) except KeyError: msg = "Unable to decode username '{}' as session key" warnings.warn(msg.format(self.user.username)) is_expired = True return is_expired def get_or_assign_number(self): """ Hook to get or to assign the customers number. It is invoked, every time an Order object is created. Using a customer number, which is different from the primary key is useful for merchants, wishing to assign sequential numbers only to customers which actually bought something. Otherwise the customer number (primary key) is increased whenever a site visitor puts something into the cart. If he never proceeds to checkout, that entity expires and may be deleted at any time in the future. """ return self.get_number() def get_number(self): """ Hook to get the customer's number. Customers haven't purchased anything may return None. """ return str(self.user_id) def save(self, **kwargs): if 'update_fields' not in kwargs: self.user.save(using=kwargs.get('using', DEFAULT_DB_ALIAS)) super(BaseCustomer, self).save(**kwargs) def delete(self, *args, **kwargs): if self.user.is_active and self.recognized is CustomerState.UNRECOGNIZED: # invalid state of customer, keep the referred User super(BaseCustomer, self).delete(*args, **kwargs) else: # also delete self through cascading self.user.delete(*args, **kwargs)
def test_value_to_string(self): f = ChoiceEnumField(enum_type=MyChoices) self.assertEqual(f.value_to_string(MyChoices.A), 'A') self.assertEqual(f.value_to_string(MyChoices.B), 'B') with self.assertRaises(ValueError): f.value_to_string(0)
def test_from_db_value(self): f = ChoiceEnumField(enum_type=MyChoices) self.assertEqual(f.from_db_value(0, None, None, None), MyChoices.A) self.assertEqual(f.from_db_value(1, None, None, None), MyChoices.B) self.assertEqual(f.from_db_value(2, None, None, None), 2)
def test_get_prep_value(self): f = ChoiceEnumField(enum_type=MyChoices) self.assertEqual(f.get_prep_value(MyChoices.A), 0) self.assertEqual(f.get_prep_value(MyChoices.B), 1) with self.assertRaises(ValueError): f.get_prep_value('X')
def test_get_prep_value(): f = ChoiceEnumField(enum_type=MyChoices) assert f.get_prep_value(MyChoices.A) is 0 assert f.get_prep_value(MyChoices.B) is 1
def test_from_db_value(): f = ChoiceEnumField(enum_type=MyChoices) assert f.from_db_value(0, None, None, None) is MyChoices.A assert f.from_db_value(1, None, None, None) is MyChoices.B assert f.from_db_value(2, None, None, None) is 2
def test_value_to_string(): obj = MyModel(f=MyChoices.A) assert ChoiceEnumField(name='f').value_to_string(obj) == 'A' with pytest.raises(ValueError): ChoiceEnumField(name='f').value_to_string(0)
def test_get_prep_value(self): f = ChoiceEnumField(enum_type=MyChoices) self.assertEqual(f.get_prep_value(MyChoices.A), 0) self.assertEqual(f.get_prep_value(MyChoices.B), 1)
class MyModel(models.Model): f = ChoiceEnumField(enum_type=MyChoices) class Meta: app_label = 'shop' managed = False
def test_value_to_string(self): obj = MyModel(f=MyChoices.A) self.assertEqual(ChoiceEnumField(name='f').value_to_string(obj), 'A') with self.assertRaises(ValueError): ChoiceEnumField(name='f').value_to_string(0)