def get_object(Model, *args, **kwargs): try: if type(Model) == QuerySet or str(type(Model)) == "<class 'django.db.models.fields.related.RelatedManager'>": return Manager.get(Model, *args, **kwargs) return Manager.get(Model.objects, *args, **kwargs) except: return None
def get_queryset(self): if hasattr(self.instance, "detail_history"): from cyano.models import Revision #print "m2m history" try: return self.instance._prefetched_objects_cache[self.prefetch_cache_name] except (AttributeError, KeyError): db = self._db or router.db_for_read(self.instance.__class__, instance=self.instance) ct_id = ContentType.objects.get_for_model(self.model).pk queryset = Manager.get_queryset(self).using(db)._next_is_sticky().all()#.filter(**self.core_filters) revision = Revision.objects.filter( object_id__in=queryset, content_type__pk=ct_id, detail_id__lte=self.instance.detail_history).order_by("-detail").first() data = [] if revision is not None: new_data = json.loads(revision.new_data) if self.prefetch_cache_name in new_data: data = new_data[self.prefetch_cache_name] ##print "History:", self.instance.detail_history, "Data:", data queryset = queryset.filter(pk__in=data) for item in queryset: setattr(item, "detail_history", self.instance.detail_history) #queryset = queryset.filter(pk__in = vals) ##print "Queryset:", queryset#, self.core_filters, self.target_field_name, self.source_field_name, self._fk_val return queryset else: queryset = super(HistoryManyRelatedManager, self).get_queryset() #print queryset return queryset
class GeoManager(Manager.from_queryset(GeoQuerySet)): "Overrides Manager to return Geographic QuerySets." # This manager should be used for queries on related fields # so that geometry columns on Oracle and MySQL are selected # properly. use_for_related_fields = True # No need to bother member with the use_for_related_fields # deprecation for this manager which is itself deprecated. silence_use_for_related_fields_deprecation = True def __init__(self, *args, **kwargs): warnings.warn( "The GeoManager class is deprecated. Simply use a normal manager " "once you have replaced all calls to GeoQuerySet methods by annotations.", RemovedInDjango20Warning, stacklevel=2) super(GeoManager, self).__init__(*args, **kwargs)
class HacsModelManager(Manager.from_queryset(HacsQuerySet)): """ """ def get_by_natural_key(self, slug, __restricted__=False): """ :param slug: :param __restricted__ :return: """ if isinstance(slug, (list, tuple)): slug = slug[0] params = { "slug": slug } if __restricted__: params["__restricted__"] = __restricted__ return self.get(**params)
class Category(MPTTModel, TimeStampedModel, SoftDeletableModel): parent = TreeForeignKey('self', null=True, blank=True, related_name='children', verbose_name=_('parent category'), on_delete=models.SET_NULL) name = models.CharField(_('name'), max_length=255, unique=True) cover = models.OneToOneField('covers.Cover', verbose_name=_('cover'), blank=True, null=True, on_delete=models.SET_NULL) slug = AutoSlugField(populate_from='name', max_length=255, allow_unicode=True, unique=True) description = models.TextField(_('description'), blank=True) objects = Manager() tree = TreeManager() class Meta: verbose_name = _('Category') verbose_name_plural = _('Categories') class MPTTMeta: order_insertion_by = ['created'] def __str__(self): return self.name
class AbstractOffer(AbstractImg): created_date = models.DateTimeField(_("Created date"), default=now) start_date = models.DateTimeField(_("Start date"), default=now) end_date = models.DateTimeField(_("End date"), default=now) title = std_text_field(_('Title')) text = models.TextField(verbose_name=_("Offer text"), blank=True) enabled = models.BooleanField(verbose_name=_("Enabled"), default=False) slug = models.CharField(verbose_name=_('URL-identifier'), max_length=100, blank=True) position = models.PositiveSmallIntegerField(verbose_name=_('Priority'), db_index=True, default=0, blank=True) objects = Manager() class Meta: verbose_name = _('Special Offer') verbose_name_plural = _('Special Offers') abstract = True
class AgentPercent(models.Model): hotel = models.ForeignKey(Hotel) date = models.DateField(verbose_name=_("From date"), db_index=True) percent = models.DecimalField(verbose_name=_('Percent'), blank=True, decimal_places=1, max_digits=4, default=0, db_index=True) class Meta: verbose_name = _("Agent Percent") verbose_name_plural = _("Agent Percents") ordering = ("hotel", ) objects = Manager() def __str__(self): return _( "For %(hotel)s on date %(date)s percent is %(percent)s") % dict( hotel=self.hotel.name, date=self.date, percent=self.percent)
def prepare_translatable_model(sender, **kwargs): model = sender if not issubclass(model, TranslatableModel) or model._meta.abstract: return if not isinstance(model._default_manager, TranslationManager): raise ImproperlyConfigured( "The default manager on a TranslatableModel must be a " "TranslationManager instance or an instance of a subclass of " "TranslationManager, the default manager of %r is not." % model) if model._meta.proxy: model._meta.translations_accessor = model._meta.concrete_model._meta.translations_accessor model._meta.translations_model = model._meta.concrete_model._meta.translations_model model._meta.translations_cache = model._meta.concrete_model._meta.translations_cache if not hasattr(model._meta, 'translations_model'): raise ImproperlyConfigured( "No TranslatedFields found on %r, subclasses of " "TranslatableModel must define TranslatedFields." % model) #### Now we have to work #### # Ensure _base_manager cannot be TranslationManager despite use_for_related_fields # 1- it is useless unless default_class is overriden # 2- in that case, _base_manager is used for saving objects and must not be # translation aware. base_mgr = getattr(model, '_base_manager', None) if base_mgr is None or isinstance(base_mgr, TranslationManager): assert django.VERSION < (1, 10) model.add_to_class('_base_manager', Manager()) # Replace get_field_by_name with one that warns for common mistakes if django.VERSION < (1, 9) and not isinstance( model._meta.get_field_by_name, SmartGetFieldByName): model._meta.get_field_by_name = MethodType( SmartGetFieldByName(model._meta.get_field_by_name), model._meta) if not isinstance(model._meta.get_field, SmartGetField): model._meta.get_field = MethodType( SmartGetField(model._meta.get_field), model._meta)
def _prepare(cls): # TODO: How do we extend the parent classes classmethod properly? # super(CachedModel, cls)._prepare() errors opts = cls._meta opts._prepare(cls) if opts.order_with_respect_to: cls.get_next_in_order = curry(cls._get_next_or_previous_in_order, is_next=True) cls.get_previous_in_order = curry(cls._get_next_or_previous_in_order, is_next=False) setattr(opts.order_with_respect_to.rel.to, 'get_%s_order' % cls.__name__.lower(), curry(method_get_order, cls)) setattr(opts.order_with_respect_to.rel.to, 'set_%s_order' % cls.__name__.lower(), curry(method_set_order, cls)) # Give the class a docstring -- its definition. if cls.__doc__ is None: cls.__doc__ = "%s(%s)" % (cls.__name__, ", ".join([f.attname for f in opts.fields])) #if hasattr(cls, 'get_absolute_url'): # cls.get_absolute_url = curry(cls.get_absolute_url, opts, cls.get_absolute_url) cls.add_to_class('cache', CacheManager()) cls.add_to_class('nocache', Manager()) cls.add_to_class('_default_manager', cls.nocache) dispatcher.send(signal=signals.class_prepared, sender=cls)
class Color(models.Model): """ Base color model """ BASE_COLOR = 0 CUSTOM_COLOR = 1 TYPES = ((BASE_COLOR, 'Base color'), (CUSTOM_COLOR, 'User color')) type = models.PositiveIntegerField(choices=TYPES) # String color in hex hex = models.CharField(max_length=6) name = models.CharField(max_length=20) description = models.CharField(max_length=100, null=True, blank=True) author = models.ForeignKey(User, on_delete=models.CASCADE) # color manages objects = Manager() base_colors = BaseColorManager() custom_color = UserColorManager() def __str__(self): return f'{self.author.__str__()} - {super().__str__()}' class Meta: ordering = ('name', )
def verify(self, authors: Manager) -> VerifiedMessage: try: author = authors.get(email=self.sender_address) except ObjectDoesNotExist: raise AuthorUnknown(self.sender_address) if not author.pgp_public_key: raise AuthorNotVerifyable(author) expected_public_key = pgpy.PGPKey() expected_public_key.parse(author.pgp_public_key) # Mandatory: Verify Signature if not self._signature: raise NoSignature(self) attached_signature = pgpy.PGPSignature() attached_signature.parse(self._signature) # Verify signature if not (attached_signature.signer_fingerprint == expected_public_key.fingerprint): raise SignatureMismatch(expected_public_key.fingerprint, attached_signature.signer_fingerprint) # Optional: If a public key was attached, verify it for good measure if self._public_key: attached_pub_key = pgpy.PGPKey() attached_pub_key.parse(self._public_key) # Verify public Key if not expected_public_key.fingerprint == attached_pub_key.fingerprint: raise PublicKeyMismatch(expected_public_key, attached_pub_key) return VerifiedMessage(subject=self._message.get('subject'), body=self._body, author=author)
class _ModelWithObjectsManagerAndDefaultMetaOptionsABC(Model): # docs.djangoproject.com/en/dev/ref/models/class/#objects objects: Manager = Manager() # docs.djangoproject.com/en/dev/ref/models/options/#model-meta-options class Meta: # pylint: disable=too-few-public-methods """Metadata.""" # docs.djangoproject.com/en/dev/ref/models/options/#abstract abstract: bool = True # docs.djangoproject.com/en/dev/ref/models/options/#app-label # app_label: str = '...' # docs.djangoproject.com/en/dev/ref/models/options/#base-manager-name base_manager_name: str = 'objects' # docs.djangoproject.com/en/dev/ref/models/options/#db-table # docs.djangoproject.com/en/dev/ref/models/options/#table-names # db_table: str = '...' # docs.djangoproject.com/en/dev/ref/models/options/#db-tablespace db_tablespace: str = '' # docs.djangoproject.com/en/dev/ref/models/options/#default-manager-name default_manager_name: str = 'objects' # docs.djangoproject.com/en/dev/ref/models/options/#default-related-name # default_related_name: str = '...' # docs.djangoproject.com/en/dev/ref/models/options/#get-latest-by # get_latest_by: Union[str, Sequence[str]] = ... # docs.djangoproject.com/en/dev/ref/models/options/#managed managed: bool = True # docs.djangoproject.com/en/dev/ref/models/options/#order-with-respect-to # order_with_respect_to: str = '...' # docs.djangoproject.com/en/dev/ref/models/options/#ordering ordering: Sequence[str] = () # docs.djangoproject.com/en/dev/ref/models/options/#permissions permissions: Sequence[tuple[str, str]] = () # docs.djangoproject.com/en/dev/ref/models/options/#default-permissions default_permissions: Sequence[str] = 'add', 'change', 'delete', 'view' # docs.djangoproject.com/en/dev/ref/models/options/#proxy proxy: bool = False # docs.djangoproject.com/en/dev/ref/models/options/#required-db-features required_db_features: Sequence[str] = () # docs.djangoproject.com/en/dev/ref/models/options/#required-db-vendor # required_db_vendor: str = '...' # docs.djangoproject.com/en/dev/ref/models/options/#select-on-save select_on_save: bool = False # docs.djangoproject.com/en/dev/ref/models/options/#indexes indexes: Sequence[Index] = () # DEPRECATED # docs.djangoproject.com/en/dev/ref/models/options/#unique-together # unique_together: Sequence[Union[str, Sequence[str]]] = () # DEPRECATED # docs.djangoproject.com/en/dev/ref/models/options/#index-together # index_together: Sequence[Union[str, Sequence[str]]] = () # docs.djangoproject.com/en/dev/ref/models/options/#constraints constraints: Sequence[BaseConstraint] = () # docs.djangoproject.com/en/dev/ref/models/options/#verbose-name # verbose_name: str = '...' # docs.djangoproject.com/en/dev/ref/models/options/#verbose-name-plural # verbose_name_plural: str = '...' def __str__(self) -> str: # pylint: disable=no-member return f'{self._meta.verbose_name} #{self.pk}'
def as_manager(cls): # Address the circular dependency between `Queryset` and `Manager`. from django.db.models.manager import Manager manager = Manager.from_queryset(cls)() manager._built_with_as_manager = True return manager
class DeploymentManager(Manager.from_queryset(JobQuerySet)): def get_queryset(self): from ralph.deployment.deployment import deploy # TODO: test it return super().get_queryset().filter( transition__actions__name=deploy.__name__)
class InvalidModel(TranslatableModel): translations = TranslatedFields(translated=models.CharField( max_length=250)) object = Manager()
class BillingDocument(models.Model): objects = Manager.from_queryset(BillingDocumentQuerySet)() class STATES(object): DRAFT = 'draft' ISSUED = 'issued' PAID = 'paid' CANCELED = 'canceled' STATE_CHOICES = Choices( (STATES.DRAFT, _('Draft')), (STATES.ISSUED, _('Issued')), (STATES.PAID, _('Paid')), (STATES.CANCELED, _('Canceled'))) series = models.CharField(max_length=20, blank=True, null=True, db_index=True) number = models.IntegerField(blank=True, null=True, db_index=True) customer = models.ForeignKey('Customer') provider = models.ForeignKey('Provider') archived_customer = JSONField() archived_provider = JSONField() due_date = models.DateField(null=True, blank=True) issue_date = models.DateField(null=True, blank=True, db_index=True) paid_date = models.DateField(null=True, blank=True) cancel_date = models.DateField(null=True, blank=True) sales_tax_percent = models.DecimalField( max_digits=4, decimal_places=2, validators=[MinValueValidator(0.0)], null=True, blank=True) sales_tax_name = models.CharField(max_length=64, blank=True, null=True) currency = models.CharField(choices=currencies, max_length=4, default='USD', help_text='The currency used for billing.') pdf = models.FileField(null=True, blank=True, editable=False, storage=_storage, upload_to=documents_pdf_path) state = FSMField(choices=STATE_CHOICES, max_length=10, default=STATES.DRAFT, verbose_name="State", help_text='The state the invoice is in.') _last_state = None class Meta: abstract = True unique_together = ('provider', 'series', 'number') ordering = ('-issue_date', 'series', '-number') def __init__(self, *args, **kwargs): super(BillingDocument, self).__init__(*args, **kwargs) self._last_state = self.state def _issue(self, issue_date=None, due_date=None): if issue_date: self.issue_date = datetime.strptime(issue_date, '%Y-%m-%d').date() elif not self.issue_date and not issue_date: self.issue_date = timezone.now().date() if due_date: self.due_date = datetime.strptime(due_date, '%Y-%m-%d').date() elif not self.due_date and not due_date: delta = timedelta(days=PAYMENT_DUE_DAYS) self.due_date = timezone.now().date() + delta if not self.sales_tax_name: self.sales_tax_name = self.customer.sales_tax_name if not self.sales_tax_percent: self.sales_tax_percent = self.customer.sales_tax_percent if not self.number: self.number = self._generate_number() self.archived_customer = self.customer.get_archivable_field_values() self._save_pdf(state=self.STATES.ISSUED) @transition(field=state, source=STATES.DRAFT, target=STATES.ISSUED) def issue(self, issue_date=None, due_date=None): self._issue(issue_date=issue_date, due_date=due_date) def _pay(self, paid_date=None): if paid_date: self.paid_date = datetime.strptime(paid_date, '%Y-%m-%d').date() if not self.paid_date and not paid_date: self.paid_date = timezone.now().date() self._save_pdf(state=self.STATES.PAID) @transition(field=state, source=STATES.ISSUED, target=STATES.PAID) def pay(self, paid_date=None): self._pay(paid_date=paid_date) def _cancel(self, cancel_date=None): if cancel_date: self.cancel_date = datetime.strptime(cancel_date, '%Y-%m-%d').date() if not self.cancel_date and not cancel_date: self.cancel_date = timezone.now().date() self._save_pdf(state=self.STATES.CANCELED) @transition(field=state, source=STATES.ISSUED, target=STATES.CANCELED) def cancel(self, cancel_date=None): self._cancel(cancel_date=cancel_date) def clone_into_draft(self): copied_fields = { 'customer': self.customer, 'provider': self.provider, 'currency': self.currency, 'sales_tax_percent': self.sales_tax_percent, 'sales_tax_name': self.sales_tax_name } clone = self.__class__._default_manager.create(**copied_fields) clone.state = self.STATES.DRAFT # clone entries too for entry in self._entries: entry_clone = entry.clone() document_type_name = self.__class__.__name__.lower() setattr(entry_clone, document_type_name, clone) entry_clone.save() clone.save() return clone def clean(self): super(BillingDocument, self).clean() # The only change that is allowed if the document is in issued state # is the state chage from issued to paid # !! TODO: If _last_state == 'issued' and self.state == 'paid' || 'canceled' # it should also be checked that the other fields are the same bc. # right now a document can be in issued state and someone could # send a request which contains the state = 'paid' and also send # other changed fields and the request would be accepted bc. only # the state is verified. if self._last_state == self.STATES.ISSUED and\ self.state not in [self.STATES.PAID, self.STATES.CANCELED]: msg = 'You cannot edit the document once it is in issued state.' raise ValidationError({NON_FIELD_ERRORS: msg}) if self._last_state == self.STATES.CANCELED: msg = 'You cannot edit the document once it is in canceled state.' raise ValidationError({NON_FIELD_ERRORS: msg}) # If it's in paid state => don't allow any changes if self._last_state == self.STATES.PAID: msg = 'You cannot edit the document once it is in paid state.' raise ValidationError({NON_FIELD_ERRORS: msg}) def save(self, *args, **kwargs): if not self.series: self.series = self.default_series # Generate the number if not self.number and self.state != BillingDocument.STATES.DRAFT: self.number = self._generate_number() # Add tax info if not self.sales_tax_name: self.sales_tax_name = self.customer.sales_tax_name if not self.sales_tax_percent: self.sales_tax_percent = self.customer.sales_tax_percent self._last_state = self.state super(BillingDocument, self).save(*args, **kwargs) def _generate_number(self, default_starting_number=1): """Generates the number for a proforma/invoice.""" default_starting_number = max(default_starting_number, 1) documents = self.__class__._default_manager.filter( provider=self.provider, series=self.series) if not documents.exists(): # An invoice/proforma with this provider and series does not exist if self.series == self.default_series: return self._starting_number else: return default_starting_number else: # An invoice with this provider and series already exists max_existing_number = documents.aggregate( Max('number'))['number__max'] if max_existing_number: if self._starting_number and self.series == self.default_series: return max(max_existing_number + 1, self._starting_number) else: return max_existing_number + 1 else: return default_starting_number def series_number(self): if self.series: if self.number: return "%s-%d" % (self.series, self.number) else: return "%s-draft-id:%d" % (self.series, self.pk) else: return "draft-id:%d" % self.pk series_number.short_description = 'Number' series_number = property(series_number) def __unicode__(self): return u'%s %s => %s [%.2f %s]' % ( self.series_number, self.provider.billing_name, self.customer.billing_name, self.total, self.currency) @property def updateable_fields(self): return [ 'customer', 'provider', 'due_date', 'issue_date', 'paid_date', 'cancel_date', 'sales_tax_percent', 'sales_tax_name', 'currency' ] @property def admin_change_url(self): url_base = 'admin:{app_label}_{klass}_change'.format( app_label=self._meta.app_label, klass=self.__class__.__name__.lower()) url = reverse(url_base, args=(self.pk, )) return '<a href="{url}">{display_series}</a>'.format( url=url, display_series=self.series_number) @property def _entries(self): # entries iterator which replaces the invoice/proforma from the DB with # self. We need this in _generate_pdf so that the data in PDF has the # lastest state for the document. Without this we get in template: # # invoice.issue_date != entry.invoice.issue_date # # which is obviously false. document_type_name = self.__class__.__name__ # Invoice or Proforma kwargs = {document_type_name.lower(): self} entries = DocumentEntry.objects.filter(**kwargs) for entry in entries: if document_type_name.lower() == 'invoice': entry.invoice = self if document_type_name.lower() == 'proforma': entry.proforma = self yield (entry) def _generate_pdf(self, state=None): customer = Customer(**self.archived_customer) provider = Provider(**self.archived_provider) if state is None: state = self.state context = { 'document': self, 'provider': provider, 'customer': customer, 'entries': self._entries, 'state': state } provider_state_template = '{provider}/{kind}_{state}_pdf.html'.format( kind=self.kind, provider=self.provider.slug, state=state).lower() provider_template = '{provider}/{kind}_pdf.html'.format( kind=self.kind, provider=self.provider.slug).lower() generic_state_template = '{kind}_{state}_pdf.html'.format( kind=self.kind, state=state).lower() generic_template = '{kind}_pdf.html'.format(kind=self.kind).lower() _templates = [ provider_state_template, provider_template, generic_state_template, generic_template ] templates = [] for t in _templates: templates.append('billing_documents/' + t) template = select_template(templates) file_object = HttpResponse(content_type='application/pdf') generate_pdf_template_object(template, file_object, context) return file_object def _save_pdf(self, state=None): file_object = self._generate_pdf(state) if file_object: pdf_content = ContentFile(file_object) filename = '{doc_type}_{series}-{number}.pdf'.format( doc_type=self.__class__.__name__, series=self.series, number=self.number) if self.pdf: self.pdf.delete() self.pdf.save(filename, pdf_content, True) else: raise RuntimeError(_('Could not generate invoice pdf.')) def serialize_hook(self, hook): """ Used to generate a skinny payload. """ return {'hook': hook.dict(), 'data': {'id': self.id}}
def prepare_translatable_model(sender, **kwargs): model = sender if not issubclass(model, TranslatableModel) or model._meta.abstract: return if not isinstance(model._default_manager, TranslationManager): raise ImproperlyConfigured( "The default manager on a TranslatableModel must be a " "TranslationManager instance or an instance of a subclass of " "TranslationManager, the default manager of %r is not." % model) # If this is a proxy model, get the concrete one concrete_model = model._meta.concrete_model if model._meta.proxy else model # Find the instance of TranslatedFields in the concrete model's dict # We cannot use _meta.get_fields here as app registry is not ready yet. found = None for relation in list(concrete_model.__dict__.keys()): try: obj = getattr(model, relation) if django.VERSION >= (1, 8): shared_model = obj.related.field.model._meta.shared_model else: shared_model = obj.related.model._meta.shared_model except AttributeError: continue if shared_model is concrete_model: if found: raise ImproperlyConfigured( "A TranslatableModel can only define one set of " "TranslatedFields, %r defines more than one: %r on %r " "and %r on %r and possibly more" % (model, obj, obj.related.model, found, found.related.model)) # Mark as found but keep looking so we catch duplicates and raise found = obj if not found: raise ImproperlyConfigured( "No TranslatedFields found on %r, subclasses of " "TranslatableModel must define TranslatedFields." % model) #### Now we have to work #### contribute_translations(model, found.related) # Ensure _base_manager cannot be TranslationManager despite use_for_related_fields # 1- it is useless unless default_class is overriden # 2- in that case, _base_manager is used for saving objects and must not be # translation aware. base_mgr = getattr(model, '_base_manager', None) if base_mgr is None or isinstance(base_mgr, TranslationManager): model.add_to_class('_base_manager', Manager()) # Replace get_field_by_name with one that warns for common mistakes if django.VERSION < (1, 9) and not isinstance( model._meta.get_field_by_name, SmartGetFieldByName): model._meta.get_field_by_name = MethodType( SmartGetFieldByName(model._meta.get_field_by_name), model._meta) if not isinstance(model._meta.get_field, SmartGetField): model._meta.get_field = MethodType( SmartGetField(model._meta.get_field), model._meta) # Attach save_translations post_save.connect(model.save_translations, sender=model, weak=False)
def as_manager(cls): # to refverify # Address the circular dependency between `Queryset` and `Manager`. from django.db.models.manager import Manager manager = Manager.from_queryset(cls)() manager._built_with_as_manager = True return manager
class Node(TimeStampedModel): name = models.CharField(max_length=255) parent = models.ForeignKey('self', null=True) objects = Manager.from_queryset(ExtendedQuerySet)()
class ModelWithMultipleManagers(models.Model): gender = models.SmallIntegerField() objects = Manager() men = MenManager() women = WomenManager()
class GameManager(Manager.from_queryset(GameQuerySet)): pass
class TreeManager(Manager.from_queryset(TreeQuerySet)): pass
class _ModelWithObjectsManagerAndDefaultMetaOptionsMixInABC(Model): # https://docs.djangoproject.com/en/dev/ref/models/class/#objects # https://docs.djangoproject.com/en/dev/ref/models/class/#django.db.models.Model.objects objects = Manager() # https://docs.djangoproject.com/en/dev/ref/models/options/#model-meta-options class Meta: # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.abstract abstract = True # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.app_label # TODO: *** Django 2 Cannot Interpolate %(app_label), etc. *** # *** so must explicitly set this in non-abstract sub-classes *** # app_label = '%(app_label)s' # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.base_manager_name base_manager_name = 'objects' # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.db_table # https://docs.djangoproject.com/en/dev/ref/models/options/#table-names # TODO: *** Django 2 Cannot Interpolate %(app_label), etc. *** # *** so must explicitly set this in non-abstract sub-classes *** db_table = '"%(app_label)s_%(object_name)s"' # note: except for Oracle, quotes have no effect # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.db_tablespace db_tablespace = None # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.default_manager_name default_manager_name = 'objects' # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.default_related_name # TODO: *** Django 2 Cannot Interpolate %(app_label), etc. *** # *** so must explicitly set this in non-abstract sub-classes *** default_related_name = '%(model_name)ss' # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.get_latest_by get_latest_by = None # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.managed managed = True # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.order_with_respect_to order_with_respect_to = None # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.ordering ordering = None # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.permissions permissions = () # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.default_permissions default_permissions = \ 'add', \ 'change', \ 'delete', \ 'view' # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.proxy proxy = False # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.required_db_features required_db_features = () # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.required_db_vendor required_db_vendor = 'postgresql' # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.select_on_save select_on_save = False # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.indexes indexes = () # (MAY BE DEPRECATED) # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.unique_together # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.index_together # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.constraints constraints = () # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.verbose_name # TODO: *** Django 2 Cannot Interpolate %(app_label), etc. *** verbose_name = '%(object_name)s' # https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.verbose_name_plural # TODO: *** Django 2 Cannot Interpolate '%(app_label)', etc. *** # *** so must explicitly set this in non-abstract sub-classes *** verbose_name_plural = '%(object_name)ss'
def manager_method_get_query_set (self, cls) : _queryset = manager_django.get_query_set(cls) return self.attach_create_index(_queryset)
class Event(StatusModel): """ Events * draft - totally invisible * planning - only event description is shown * active - event is scheduled, speakers also visible * archived - event passed, registration is disabled """ STATUS = Choices( 'planning', 'active', 'archived', 'draft', ) name = models.CharField(u'Название', max_length=1024) number = models.SmallIntegerField(u'Номер', blank=True, null=True) description = models.TextField(u'Описание', blank=True) image = models.ImageField(u'Изображение', upload_to='events', null=True, blank=True) date = models.DateTimeField(u'Начало', blank=True, null=True) venue = models.ForeignKey('Venue', blank=True, null=True) sponsors = models.ManyToManyField('Sponsor', verbose_name=u'Спонсоры', blank=True) registration_link = models.URLField(u'Ссылка на событие', blank=True) streaming_url = models.URLField(u'Ссылка на трансляцию', blank=True) streaming_embed = models.TextField( u'Embed трансляции', blank=True, help_text='html с ютуба или другого источника') manual_on_air = models.NullBooleanField( u'Включить трансляцию', default=None, help_text=u'Включается автоматически за полчаса до начала и идёт 4 часа.' u' Нужно, для тестирования в другое время.') # Deprecated: timepad_id = models.IntegerField(u'ID события на Timepad', blank=True, default=0, editable=False) votable = models.BooleanField(u'Включить голосование', default=False, editable=False) objects = Manager() visible = QueryManager( status__in=[STATUS.planning, STATUS.active, STATUS.archived]) future = QueryManager(status__in=[STATUS.planning, STATUS.active]) def __str__(self): if self.number: return u'{0} №{1}'.format(self.name, self.number) else: return self.name def __repr__(self): return '<Event №%s>' % self.number @permalink def get_absolute_url(self): return 'event', [self.number] @property def is_active(self): return self.status == self.STATUS.active def days_delta(self): if not self.date: return None delta = (self.date.date() - datetime.datetime.today().date()).days if delta < 0: return None # passed if delta >= 0: return delta @property def on_air(self): if self.manual_on_air is not None: return self.manual_on_air datetime_start = self.date - datetime.timedelta(minutes=30) datetime_stop = self.date + datetime.timedelta( hours=4) # Actually meetups are not that long return datetime_start <= datetime.datetime.now() <= datetime_stop def get_registration_url(self): if self.timepad_id: return 'https://moscowdjango.timepad.ru/event/%s/' % self.timepad_id if self.registration_link: return self.registration_link @classmethod def spotlight(cls, with_drafts=False): """ Last active or last planned or last archived """ try: if with_drafts: return Event.objects.latest() return Event.future.latest() except Event.DoesNotExist: return None class Meta: verbose_name = u'Событие' verbose_name_plural = u'События' get_latest_by = 'number' ordering = ['-date']
class ResourceGroupManager(Manager.from_queryset(ResourceGroupQuerySet)): pass
class Hotel(AbstractName, AbstractGeo, HotelPoints): register_date = models.DateTimeField(_("Register from"), default=now) email = models.CharField(verbose_name=_("Email"), blank=True, max_length=75) phone = models.CharField(max_length=100, verbose_name=_('Phone'), blank=True) fax = models.CharField(max_length=100, verbose_name=_('Fax'), blank=True) website = models.URLField(max_length=150, verbose_name=_('Website'), blank=True) contact_email = models.CharField(verbose_name=_("Contact Email"), blank=True, max_length=75) contact_name = models.CharField(max_length=100, verbose_name=_('Contact Name'), blank=True) room_count = models.IntegerField(_('Count of Rooms'), blank=True, default=0) option = models.ManyToManyField(HotelOption, verbose_name=_('Hotel Options'), blank=True) starcount = models.IntegerField(_("Count of Stars"), choices=STAR_CHOICES, default=UNKNOWN_STAR, db_index=True) choice = models.IntegerField(_("Type of Hotel"), choices=HOTEL_CHOICES, default=HOTEL_HOTEL, editable=False, db_index=True) admins = models.ManyToManyField(settings.AUTH_USER_MODEL, verbose_name=_('Hotel Admins'), blank=True) point = models.DecimalField(_("Point of hotel"), editable=False, default=0, decimal_places=1, max_digits=4, db_index=True) best_offer = models.BooleanField(verbose_name=_("Best offer"), default=False, db_index=True) in_top10 = models.BooleanField(verbose_name=_("In top 10"), default=False, db_index=True) current_amount = models.DecimalField(verbose_name=_('Current amount'), default=0, max_digits=20, decimal_places=3, db_index=True) booking_terms = models.TextField(verbose_name=_("Booking terms"), blank=True) schema_transit = models.TextField(verbose_name=_("Schema of transit"), blank=True) booking_terms_en = models.TextField( verbose_name=_("Booking terms(English)"), blank=True) schema_transit_en = models.TextField( verbose_name=_("Schema of transit(English)"), blank=True) payment_method = models.ManyToManyField(PaymentMethod, verbose_name=_('Payment methods'), blank=True) updated_date = models.DateTimeField(_("Updated date"), null=True, blank=True) condition_cancellation = models.TextField( verbose_name=_("Condition cancellation"), blank=True) condition_cancellation_en = models.TextField( verbose_name=_("Condition cancellation(English)"), blank=True) paid_services = models.TextField(verbose_name=_("Paid services"), blank=True) paid_services_en = models.TextField( verbose_name=_("Paid services(English)"), blank=True) time_on = models.CharField(max_length=5, verbose_name=_('Time on'), blank=True) time_off = models.CharField(max_length=5, verbose_name=_('Time off'), blank=True) work_on_request = models.BooleanField(verbose_name=_("Work on request"), default=False, db_index=True) hoteltype = models.ForeignKey(HotelType, verbose_name=_('Hotel type'), null=True, blank=True, db_index=True) addon_city = models.ForeignKey(City, verbose_name=_('Main city'), related_name='main_city', null=True, blank=True, db_index=True) class Meta: verbose_name = _("Hotel") verbose_name_plural = _("Hotels") ordering = ("name", ) objects = Manager() def get_address(self): if get_language() == 'en': if self.address_en: return self.address_en return self.address def get_schema_transit(self): if get_language() == 'en': if self.schema_transit_en: return self.schema_transit_en return self.schema_transit def get_booking_terms(self): if get_language() == 'en': if self.booking_terms_en: return self.booking_terms_en return self.booking_terms def get_condition_cancellation(self): if get_language() == 'en': if self.condition_cancellation_en: return self.condition_cancellation_en return self.condition_cancellation def get_paid_services(self): if get_language() == 'en': if self.paid_services_en: return self.paid_services_en return self.paid_services @property def metadesc(self): r = self.description if get_language() == 'en' and self.description_en: r = self.description_en return r.split('. ')[0] + '.' def get_count_stars_hotels(self): qs = Hotel.objects.filter(city=self.city) two = qs(starcount=TWO_STAR).count() three = qs(starcount=THREE_STAR).count() four = qs(starcount=FOUR_STAR).count() five = qs(starcount=FIVE_STAR).count() return [two, three, four, five] def fulladdress(self): return "%s, %s" % (self.address, self.city.name) def in_city(self): return Hotel.objects.filter(city=self.city).count() def in_system(self): return Hotel.objects.all().count() def stars(self): if self.starcount == -10: return None elif self.starcount == -1: return 'apartaments' elif self.starcount == -2: return 'hostel' elif not self.starcount: return 'mini' else: return range(0, int(self.starcount)) def all_room_options(self): return RoomOption.objects.filter( enabled=True, room__hotel=self).select_related().order_by( 'category', 'position', 'name').distinct() def get_absolute_url(self): return reverse('hotel_detail', kwargs={ 'city': self.city.slug, 'slug': self.slug }) def get_cabinet_url(self): return reverse('cabinet_info', kwargs={ 'city': self.city.slug, 'slug': self.slug }) def get_current_percent(self): try: return AgentPercent.objects.filter(hotel=self).filter( date__lte=now()).order_by('-date')[0].percent except IndexError as ierr: return None def get_percent_on_date(self, on_date): return AgentPercent.objects.filter(hotel=self).filter( date__lte=on_date).order_by('-date')[0].percent @property def min_current_amount(self): return self.amount_on_date(now()) def amount_on_date(self, on_date): result = PlacePrice.objects.filter(settlement__room__hotel=self, settlement__enabled=True, date=on_date).\ aggregate(Min('amount')) amount = result['amount__min'] if amount: return amount return 0 def save(self, *args, **kwargs): if not self.slug: if not self.pk: super(Hotel, self).save(*args, **kwargs) self.slug = self.pk else: self.slug = self.slug.strip().replace(' ', '-') if Hotel.objects.filter( slug=self.slug, city=self.city).exclude(pk=self.pk).count(): self.slug = self.pk self.updated_date = now() super(Hotel, self).save(*args, **kwargs) def update_hotel_amount(self): amount = self.min_current_amount if amount: self.current_amount = amount else: self.current_amount = 0 self.save() def tourism_places(self): places = Tourism.objects.raw( places_near_object(self, settings.TOURISM_PLACES_RADIUS, 'address_tourism')) all_places = [] for p in places: all_places.append(p.id) return Tourism.objects.filter(pk__in=all_places).order_by('category') def complete_booking_users_id(self): # TODO Check status of bookings users_id = Booking.objects.filter(hotel=self).values_list('user', flat=True) return users_id def __str__(self): # noinspection PyBroadException try: return _("%(hotel)s :: %(city)s") % { 'hotel': self.get_name, 'city': self.city.get_name, } except: return self.name def available_rooms_for_guests_in_period(self, guests, from_date, to_date): # Find available rooms for this guests count and for searched dates need_days = (to_date - from_date).days date_period = (from_date, to_date - timedelta(days=1)) rooms_with_amount = SettlementVariant.objects.filter(enabled=True, settlement__gte=guests, room__hotel=self, placeprice__date__range=date_period, placeprice__amount__gt=0).\ annotate(num_days=Count('pk')).\ filter(num_days__gte=need_days).order_by('room__pk').values_list('room__pk', flat=True).distinct() room_not_avail = Room.objects.filter(pk__in=rooms_with_amount, availability__date__range=date_period, availability__min_days__gt=need_days).\ annotate(num_days=Count('pk')).filter(num_days__gt=0).order_by('pk').\ values_list('pk', flat=True).distinct() rooms = Room.objects.exclude(pk__in=room_not_avail).filter(pk__in=rooms_with_amount, availability__date__range=date_period, availability__placecount__gt=0).\ annotate(num_days=Count('pk')).filter(num_days__gte=need_days) return rooms
class OrderBookSwaps(models.Model): STATE_CREATED = 'created' STATE_ACTIVE = 'active' STATE_EXPIRED = 'expired' STATE_POSTPONED = 'postponed' STATE_DONE = 'done' STATE_CANCELLED = 'cancelled' STATE_HIDDEN = 'hidden' ORDER_STATES = ( (STATE_CREATED, 'CREATED'), (STATE_ACTIVE, 'ACTIVE'), (STATE_EXPIRED, 'EXPIRED'), (STATE_POSTPONED, 'POSTPONED'), (STATE_DONE, 'DONE'), (STATE_CANCELLED, 'CANCELLED'), (STATE_HIDDEN, 'HIDDEN'), ) name = models.CharField(max_length=512, null=True, default='') memo_contract = models.CharField(max_length=70, null=True, default=_get_memo) network = models.ForeignKey(Network, on_delete=models.PROTECT, related_name='orders', default=1) contract_address = models.CharField(max_length=255, verbose_name='Contract address', default='') # base_coin_id = models.IntegerField(default=0) base_address = models.CharField(max_length=50, null=True, default='') base_limit = models.DecimalField( max_digits=50, decimal_places=18, ) # quote_coin_id = models.IntegerField(default=0) quote_address = models.CharField(max_length=50, null=True, default='') quote_limit = models.DecimalField( max_digits=50, decimal_places=18, ) user = models.ForeignKey( User, on_delete=models.PROTECT, related_name='orders', ) owner_address = models.CharField(max_length=50, null=True, default='') exchange_user = models.CharField(max_length=512, null=True, default='') broker_fee = models.BooleanField(default=False) broker_fee_address = models.CharField(max_length=50, null=True, default='') broker_fee_base = models.FloatField(null=True, default=0) broker_fee_quote = models.FloatField(null=True, default=0) min_base_wei = models.CharField(max_length=512, null=True, default='') min_quote_wei = models.CharField(max_length=512, null=True, default='') base_amount_contributed = models.DecimalField(max_digits=MAX_WEI_DIGITS, decimal_places=0, default=0) base_amount_total = models.DecimalField(max_digits=MAX_WEI_DIGITS, decimal_places=0, default=0) quote_amount_contributed = models.DecimalField(max_digits=MAX_WEI_DIGITS, decimal_places=0, default=0) quote_amount_total = models.DecimalField(max_digits=MAX_WEI_DIGITS, decimal_places=0, default=0) public = models.BooleanField(default=True) unique_link = models.CharField(max_length=50, null=True, unique=True, default=_get_unique_link) created_date = models.DateTimeField(auto_now_add=True) stop_date = models.DateTimeField(default=timezone.now) contract_state = models.CharField( max_length=63, choices=ORDER_STATES, default=STATE_CREATED, ) state = models.CharField( max_length=63, choices=ORDER_STATES, default=STATE_CREATED, ) state_changed_at = models.DateTimeField(auto_now_add=True) whitelist = models.BooleanField(default=False) whitelist_address = models.CharField(max_length=50, null=True) swap_ether_contract = models.ForeignKey(Contract, null=True) is_exchange = models.BooleanField(default=False) notification = models.BooleanField(default=False) notification_email = models.CharField(max_length=50, null=True, default='') notification_telegram_name = models.CharField(max_length=50, null=True, default='') comment = models.TextField(default='') is_rubic_order = models.BooleanField(default=False) rubic_initialized = models.BooleanField(default=False) is_displayed = models.BooleanField(default=True) is_closed_by_limiter = models.BooleanField(default=False) # ! --- swaped_on_uniswap = models.BooleanField(default=False) # -- # !--- Managers objects = Manager() public_active_orders = PublicActiveOrdersManager(state=STATE_ACTIVE) # --- class Meta: indexes = (models.Index(fields=[ 'id', 'unique_link', ]), ) def __str__(self): return f'Order "{self.name}" (unique link: {self.unique_link})' @check_transaction def msg_deployed(self): self.state = self.STATE_ACTIVE self.contract_state = self.STATE_ACTIVE self.save() if self.user.email: swaps_link = '{protocol}://{url}/public-v3/{unique_link}'.format( protocol=SITE_PROTOCOL, unique_link=self.unique_link, url=SWAPS_URL) sendEMail(swaps_deploed_subject, swaps_deploed_message.format(swaps_link=swaps_link), [self.user.email]) def finalized(self): self.state = self.STATE_DONE self.contract_state = self.STATE_DONE self.state_changed_at = datetime.utcnow() self.save() def cancelled(self): self.state = self.STATE_CANCELLED self.contract_state = self.STATE_CANCELLED self.state_changed_at = datetime.utcnow() self.save() def deposit_order(self, message): msg_amount = message['amount'] base_address = self.base_address.lower() quote_address = self.quote_address.lower() if message['token'] == base_address or message[ 'token'] == quote_address: if message['token'] == self.base_address: self.base_amount_contributed += msg_amount self.base_amount_total += msg_amount else: self.quote_amount_contributed += msg_amount self.quote_amount_total += msg_amount self.save() def refund_order(self, message): msg_amount = message['amount'] base_address = self.base_address.lower() quote_address = self.quote_address.lower() if message['token'] == base_address or message[ 'token'] == quote_address: if message['token'] == self.base_address: self.base_amount_contributed -= msg_amount else: self.quote_amount_contributed -= msg_amount self.save() def save(self, *args, **kwargs): self.base_address = self.base_address.lower() self.quote_address = self.quote_address.lower() self.owner_address = self.owner_address.lower() self.broker_fee_address = self.broker_fee_address.lower() return super().save(*args, **kwargs)
class Room(AbstractName): option = models.ManyToManyField(RoomOption, verbose_name=_('Availability options'), blank=True) hotel = models.ForeignKey(Hotel, verbose_name=_('Hotel'), null=True, blank=True) places = models.IntegerField(_("Place Count"), choices=PLACES_CHOICES, default=PLACES_UNKNOWN, db_index=True) typefood = models.IntegerField(_("Type of food"), choices=TYPEFOOD, default=TYPEFOOD_RO, db_index=True) surface_area = models.PositiveSmallIntegerField( verbose_name=_('Surface area (m2)'), default=0, db_index=True) class Meta: verbose_name = _("Room") verbose_name_plural = _("Rooms") objects = Manager() def __str__(self): try: return _("%(room)s :: %(places)s :: %(hotel)s") % { 'room': self.get_name, 'places': self.places, 'hotel': self.hotel.get_name } except: return self.name @property def metadesc(self): r = self.description if get_language() == 'en' and self.description_en: r = self.description_en return r.split('. ')[0] + '.' @property def min_current_amount(self): return self.amount_on_date(now()) def amount_on_date(self, on_date, guests=None): result = PlacePrice.objects.filter(settlement__room=self, settlement__enabled=True, date=on_date).\ aggregate(Min('amount')) amount = result['amount__min'] if amount: return amount return 0 def amount_date_guests(self, on_date, guests): # noinspection PyBroadException try: s = SettlementVariant.objects.select_related().filter(room=self, enabled=True, settlement__gte=guests).\ order_by('settlement')[0] return s.amount_on_date(on_date) except: return None def discount_on_date(self, on_date): # noinspection PyBroadException try: return Discount.objects.get(room=self, date=on_date).discount except: return None def settlement_on_date_for_guests(self, on_date, guests): result = SettlementVariant.objects.filter(room=self, enabled=True, settlement__gte=guests).\ aggregate(Min('settlement')) return result['settlement__min'] def active_settlements(self): return SettlementVariant.objects.filter( room=self, enabled=True).order_by('settlement') def get_absolute_url(self): return reverse('room_detail', kwargs={ 'city': self.hotel.city.slug, 'slug': self.hotel.slug, 'pk': self.pk }) def active_discounts(self): discounts = RoomDiscount.objects.filter(room=self, discount__enabled=True).\ values_list('discount__pk', flat=True).distinct() return Discount.objects.filter(pk__in=discounts).order_by('pk') def inactive_discounts(self): discounts = RoomDiscount.objects.filter(room=self, discount__enabled=True).\ values_list('discount__pk', flat=True).distinct() return Discount.objects.filter(hotel=self.hotel).exclude( pk__in=discounts).order_by('pk') @property def simple_discount(self): result, created = SimpleDiscount.objects.get_or_create(room=self) return result
class Payment(models.Model): objects = Manager.from_queryset(PaymentQuerySet)() amount = models.DecimalField( decimal_places=2, max_digits=8, validators=[MinValueValidator(Decimal('0.00'))]) due_date = models.DateField(null=True, blank=True, default=None) class Status(object): Unpaid = 'unpaid' Pending = 'pending' Paid = 'paid' Canceled = 'canceled' FinalStatuses = [Paid, Canceled] STATUS_CHOICES = ((Status.Unpaid, _('Unpaid')), (Status.Pending, _('Pending')), (Status.Paid, _('Paid')), (Status.Canceled, _('Canceled'))) status = FSMField(max_length=8, choices=STATUS_CHOICES, default=Status.Unpaid) customer = models.ForeignKey(Customer) provider = models.ForeignKey(Provider) proforma = models.OneToOneField("Proforma", null=True, blank=True, related_name='proforma_payment') invoice = models.OneToOneField("Invoice", null=True, blank=True, related_name='invoice_payment') visible = models.BooleanField(default=True) currency = models.CharField(choices=currencies, max_length=4, default='USD', help_text='The currency used for billing.') currency_rate_date = models.DateField(blank=True, null=True) @transition(field='status', source=[Status.Unpaid, Status.Pending], target=Status.Canceled) def cancel(self): pass @transition(field='status', source=Status.Unpaid, target=Status.Pending) def process(self): pass @transition(field='status', source=(Status.Unpaid, Status.Pending), target=Status.Paid) def succeed(self): pass @transition(field='status', source=Status.Pending, target=Status.Unpaid) def fail(self): pass def clean(self): document = self.invoice or self.proforma if document: if document.provider != self.provider: raise ValidationError( 'Provider doesn\'t match with the one in documents.') if document.customer != self.customer: raise ValidationError( 'Customer doesn\'t match with the one in documents.') if self.invoice and self.proforma: if self.invoice.proforma != self.proforma: raise ValidationError('Invoice and proforma are not related.') def _log_unsuccessful_transition(self, transition_name): logger.warning( '[Models][Payment]: %s', { 'detail': 'Couldn\'t %s payment' % transition_name, 'payment_id': self.id, 'customer_id': self.customer.id }) @property def is_overdue(self): if self.status == Payment.Status.Unpaid and self.days_left <= 0: return True return False @property def days_left(self): return (self.due_date - date.today()).days def __unicode__(self): return '#%0#5d' % self.pk def diff(self, other_payment): changes = {} for attr in [ 'amount', 'due_date', 'status', 'customer', 'provider', 'proforma', 'invoice', 'visible', 'currency', 'currency_rate_date' ]: if not hasattr(other_payment, attr) or not hasattr(self, attr): continue current = getattr(self, attr, None) other = getattr(other_payment, attr, None) if current != other: changes[attr] = {'from': current, 'to': other} return changes
class Booking(MoneyBase, AbstractIP): user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('User'), blank=True, null=True) date = models.DateTimeField(verbose_name=_("Creation date"), default=now) system_id = models.IntegerField(_("ID in system"), default=0) from_date = models.DateField(_("From")) to_date = models.DateField(_("To")) settlement = models.ForeignKey(SettlementVariant, verbose_name=_('Settlement Variant'), null=True, on_delete=models.SET_NULL) settlement_txt = models.CharField( verbose_name=_("Settlement Variant in text"), max_length=255, blank=True) hotel = models.ForeignKey(Hotel, verbose_name=_('Hotel'), blank=True, null=True, on_delete=models.SET_NULL) hotel_txt = models.CharField(verbose_name=_("Hotel in text"), max_length=255, blank=True) status = models.IntegerField(_("Booking status"), choices=STATUS_CHOICES, default=STATUS_UNKNOWN) first_name = models.CharField(verbose_name=_("First name"), max_length=100) middle_name = models.CharField(verbose_name=_("Middle name"), max_length=100, blank=True) last_name = models.CharField(verbose_name=_("Last name"), max_length=100) phone = models.CharField(max_length=100, verbose_name=_('Phone'), blank=True) email = models.CharField(_('E-mail'), blank=True, max_length=100) uuid = models.CharField(verbose_name=_("Unique ID"), max_length=64, blank=True, editable=False) commission = models.DecimalField(verbose_name=_('Commission'), default=0, max_digits=20, decimal_places=3) hotel_sum = models.DecimalField(verbose_name=_('Hotel Sum'), default=0, max_digits=20, decimal_places=3) card_number = models.CharField(verbose_name=_("Card number"), max_length=16, blank=True) card_valid = models.CharField(verbose_name=_("Card valid to"), max_length=5, blank=True) card_holder = models.CharField(verbose_name=_("Card holder"), max_length=50, blank=True) card_cvv2 = models.CharField( verbose_name=_("Card verification value(CVV2)"), max_length=4, blank=True) payment_method = models.ForeignKey(PaymentMethod, verbose_name=_('Payment method'), null=True) enabled = models.BooleanField(verbose_name=_('Enabled'), default=False, db_index=True) guests = models.PositiveSmallIntegerField(_("Guests"), db_index=True, default=0) btype = models.IntegerField(_("Booking type"), choices=BOOKING_CHOICES, default=BOOKING_UNKNOWN) bdiscount = models.PositiveSmallIntegerField( verbose_name=_('Discount percent'), default=0, db_index=True) typefood = models.IntegerField(_("Type of food"), choices=TYPEFOOD, db_index=True, null=True) freecancel = models.PositiveSmallIntegerField( verbose_name=_('Free cancel days'), default=0, db_index=True) penaltycancel = models.DecimalField( verbose_name=_('Penalty for cancellation'), default=0, max_digits=20, decimal_places=3) comment = models.TextField(verbose_name=_("Client comment"), blank=True, default='') amount_no_discount = models.DecimalField( verbose_name=_('Amount without discount'), default=0, max_digits=22, decimal_places=5, db_index=True) cancel_time = models.DateTimeField( verbose_name=_("Time/date of cancellation"), blank=True, null=True) objects = Manager() class Meta: ordering = ("-date", ) verbose_name = _("Booking") verbose_name_plural = _("Bookings") def __str__(self): return "Booking - %s" % self.pk @property def days(self): return (self.to_date - self.from_date).days @property def freecancel_before(self): if self.freecancel > 0: return self.from_date - timedelta(days=self.freecancel) return False @property def allow_penalty(self): if self.freecancel_before and self.hotel and self.btype == BOOKING_GB: offset = self.hotel.city.time_offset for_time = self.hotel.time_on for_time1 = time(int(for_time[:2]), int(for_time[3:5])) if now() > datetime.combine(self.freecancel_before, for_time1) - timedelta(hours=offset): return True return False def get_absolute_url(self): if not self.uuid: self.save() return reverse('booking_hotel_detail', kwargs={'slug': self.uuid}) def get_client_url(self): if not self.uuid: self.save() return reverse('booking_user_detail', kwargs={'slug': self.uuid}) @property def room_day_cost(self): return self.amount / self.days @property def room_day_cost_no_amount(self): if self.amount_no_discount > 0: return self.amount_no_discount / self.days if self.bdiscount > 0: return ((self.amount * 100) / (100 - self.bdiscount)) / self.days return self.room_day_cost def save(self, *args, **kwargs): if not self.uuid: self.uuid = uuid4() if self.system_id < 1: new_id = random.randint(100000000, 999999999) while Booking.objects.filter(system_id=new_id).count() > 0: new_id = random.randint(100000000, 999999999) self.system_id = new_id super(Booking, self).save(*args, **kwargs)
class HorizontalManager(Manager.from_queryset(QuerySet)): use_for_related_fields = True use_in_migrations = True def __init__(self): super(HorizontalManager, self).__init__()
class Child(TimeStampedModel): name = models.CharField(max_length=255) parent = models.ForeignKey(Parent, null=True, on_delete=models.CASCADE) objects = Manager.from_queryset(ExtendedQuerySet)()