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.4KB

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