You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

abstract_models.py 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import hashlib
  2. import random
  3. import six
  4. from django.db import models
  5. from django.utils.translation import ugettext_lazy as _
  6. from django.core.urlresolvers import reverse
  7. from oscar.core.compat import AUTH_USER_MODEL
  8. class AbstractWishList(models.Model):
  9. """
  10. Represents a user's wish lists of products.
  11. A user can have multiple wish lists, move products between them, etc.
  12. """
  13. # Only authenticated users can have wishlists
  14. owner = models.ForeignKey(AUTH_USER_MODEL, related_name='wishlists',
  15. verbose_name=_('Owner'))
  16. name = models.CharField(verbose_name=_('Name'), default=_('Default'),
  17. max_length=255)
  18. #: This key acts as primary key and is used instead of an int to make it
  19. #: harder to guess
  20. key = models.CharField(_('Key'), max_length=6, db_index=True, unique=True,
  21. editable=False)
  22. # Oscar core does not support public or shared wishlists at the moment, but
  23. # all the right hooks should be there
  24. PUBLIC, PRIVATE, SHARED = ('Public', 'Private', 'Shared')
  25. VISIBILITY_CHOICES = (
  26. (PRIVATE, _('Private - Only the owner can see the wish list')),
  27. (SHARED, _('Shared - Only the owner and people with access to the'
  28. ' obfuscated link can see the wish list')),
  29. (PUBLIC, _('Public - Everybody can see the wish list')),
  30. )
  31. visibility = models.CharField(_('Visibility'), max_length=20,
  32. default=PRIVATE, choices=VISIBILITY_CHOICES)
  33. # Convention: A user can have multiple wish lists. The last created wish
  34. # list for a user shall be her "default" wish list.
  35. # If an UI element only allows adding to wish list without
  36. # specifying which one , one shall use the default one.
  37. # That is a rare enough case to handle it by convention instead of a
  38. # BooleanField.
  39. date_created = models.DateTimeField(
  40. _('Date created'), auto_now_add=True, editable=False)
  41. def __unicode__(self):
  42. return u"%s's Wish List '%s'" % (self.owner, self.name)
  43. def save(self, *args, **kwargs):
  44. if not self.pk or kwargs.get('force_insert', False):
  45. self.key = self.__class__.random_key()
  46. super(AbstractWishList, self).save(*args, **kwargs)
  47. @classmethod
  48. def random_key(cls, length=6):
  49. """
  50. Get a unique random generated key based on SHA-1 and owner
  51. """
  52. while True:
  53. rand = six.text_type(random.random()).encode('utf8')
  54. key = hashlib.sha1(rand).hexdigest()[:length]
  55. if not cls._default_manager.filter(key=key).exists():
  56. return key
  57. def is_allowed_to_see(self, user):
  58. if self.visibility in (self.PUBLIC, self.SHARED):
  59. return True
  60. else:
  61. return user == self.owner
  62. def is_allowed_to_edit(self, user):
  63. # currently only the owner can edit her wish list
  64. return user == self.owner
  65. class Meta:
  66. ordering = ('owner', 'date_created', )
  67. verbose_name = _('Wish List')
  68. abstract = True
  69. def get_absolute_url(self):
  70. return reverse('customer:wishlists-detail', kwargs={
  71. 'key': self.key})
  72. def add(self, product):
  73. """
  74. Add a product to this wishlist
  75. """
  76. lines = self.lines.filter(product=product)
  77. if len(lines) == 0:
  78. self.lines.create(
  79. product=product, title=product.get_title())
  80. else:
  81. line = lines[0]
  82. line.quantity += 1
  83. line.save()
  84. class AbstractLine(models.Model):
  85. """
  86. One entry in a wish list. Similar to order lines or basket lines.
  87. """
  88. wishlist = models.ForeignKey('wishlists.WishList', related_name='lines',
  89. verbose_name=_('Wish List'))
  90. product = models.ForeignKey(
  91. 'catalogue.Product', verbose_name=_('Product'),
  92. related_name='wishlists_lines', on_delete=models.SET_NULL,
  93. blank=True, null=True)
  94. quantity = models.PositiveIntegerField(_('Quantity'), default=1)
  95. #: Store the title in case product gets deleted
  96. title = models.CharField(_("Title"), max_length=255)
  97. def __unicode__(self):
  98. return u'%sx %s on %s' % (self.quantity, self.title,
  99. self.wishlist.name)
  100. def get_title(self):
  101. if self.product:
  102. return self.product.get_title()
  103. else:
  104. return self.title
  105. class Meta:
  106. abstract = True
  107. verbose_name = _('Wish list line')
  108. unique_together = (('wishlist', 'product'), )