def test_loading_classes_defined_in_both_local_and_izi_modules(self): with override_settings(INSTALLED_APPS=self.installed_apps): (Free, FixedPrice) = get_classes('shipping.methods', ('Free', 'FixedPrice')) self.assertEqual('tests._site.shipping.methods', Free.__module__) self.assertEqual('izi.apps.shipping.methods', FixedPrice.__module__)
def test_load_overriden_3rd_party_class_correctly(self): self.installed_apps.append('apps.myapp') with override_settings(INSTALLED_APPS=self.installed_apps): Cow, Goat = get_classes('myapp.models', ('Cow', 'Goat'), self.core_app_prefix) self.assertEqual('thirdparty_package.apps.myapp.models', Cow.__module__) self.assertEqual('apps.myapp.models', Goat.__module__)
def test_loading_classes_with_root_app(self): import tests._site.shipping path = dirname(dirname(tests._site.shipping.__file__)) with temporary_python_path([path]): self.installed_apps[self.installed_apps.index( 'tests._site.shipping')] = 'shipping' with override_settings(INSTALLED_APPS=self.installed_apps): (Free, ) = get_classes('shipping.methods', ('Free', )) self.assertEqual('shipping.methods', Free.__module__)
from django.test import TestCase from izi.apps.dashboard.promotions import forms from izi.core.loading import get_classes RawHTML, PagePromotion = get_classes('promotions.models', ['RawHTML', 'PagePromotion']) class TestPagePromotionForm(TestCase): def test_page_promotion_has_fields(self): promotion = RawHTML() promotion.save() instance = PagePromotion(content_object=promotion) data = {'position': 'page', 'page_url': '/'} form = forms.PagePromotionForm(data=data, instance=instance) self.assertTrue(form.is_valid()) page_promotion = form.save() self.assertEqual(page_promotion.page_url, '/')
import logging from django.db import IntegrityError from django.db.models import F from django.dispatch import receiver from izi.apps.basket.signals import basket_addition from izi.apps.catalogue.signals import product_viewed from izi.apps.order.signals import order_placed from izi.apps.search.signals import user_search from izi.core.loading import get_classes UserSearch, UserRecord, ProductRecord, UserProductView = get_classes( 'analytics.models', ['UserSearch', 'UserRecord', 'ProductRecord', 'UserProductView']) # Helpers logger = logging.getLogger('izi.analytics') def _update_counter(model, field_name, filter_kwargs, increment=1): """ Efficiently updates a counter field by a given increment. Uses Django's update() call to fetch and update in one query. TODO: This has a race condition, we should use UPSERT here :param model: The model class of the recording model :param field_name: The name of the field to update :param filter_kwargs: Parameters to the ORM's filter() function to get the
def test_loading_class_from_module_not_defined_in_local_app(self): with override_settings(INSTALLED_APPS=self.installed_apps): (Repository, ) = get_classes('shipping.repository', ('Repository', )) self.assertEqual('izi.apps.shipping.repository', Repository.__module__)
def test_loading_class_defined_in_local_module(self): with override_settings(INSTALLED_APPS=self.installed_apps): (Free, ) = get_classes('shipping.methods', ('Free', )) self.assertEqual('tests._site.shipping.methods', Free.__module__)
from django_tables2 import SingleTableMixin, SingleTableView from izi.core.loading import get_classes, get_model from izi.views.generic import ObjectLookupView (ProductForm, ProductClassSelectForm, ProductSearchForm, ProductClassForm, CategoryForm, StockAlertSearchForm, AttributeOptionGroupForm) \ = get_classes('dashboard.catalogue.forms', ('ProductForm', 'ProductClassSelectForm', 'ProductSearchForm', 'ProductClassForm', 'CategoryForm', 'StockAlertSearchForm', 'AttributeOptionGroupForm')) (StockRecordFormSet, ProductCategoryFormSet, ProductImageFormSet, ProductRecommendationFormSet, ProductAttributesFormSet, AttributeOptionFormSet) \ = get_classes('dashboard.catalogue.formsets', ('StockRecordFormSet', 'ProductCategoryFormSet', 'ProductImageFormSet', 'ProductRecommendationFormSet', 'ProductAttributesFormSet',
from izi.core.loading import get_class, get_classes OrderReportGenerator = get_class('order.reports', 'OrderReportGenerator') ProductReportGenerator, UserReportGenerator \ = get_classes('analytics.reports', ['ProductReportGenerator', 'UserReportGenerator']) OpenBasketReportGenerator, SubmittedBasketReportGenerator \ = get_classes('basket.reports', ['OpenBasketReportGenerator', 'SubmittedBasketReportGenerator']) OfferReportGenerator = get_class('offer.reports', 'OfferReportGenerator') VoucherReportGenerator = get_class('voucher.reports', 'VoucherReportGenerator') class GeneratorRepository(object): generators = [OrderReportGenerator, ProductReportGenerator, UserReportGenerator, OpenBasketReportGenerator, SubmittedBasketReportGenerator, VoucherReportGenerator, OfferReportGenerator] def get_report_generators(self): return self.generators def get_generator(self, code): for generator in self.generators: if generator.code == code: return generator return None
from django.shortcuts import get_object_or_404, redirect from django.template.loader import render_to_string from django.urls import reverse, reverse_lazy from django.utils.translation import gettext_lazy as _ from django.views import generic from izi.apps.customer.utils import normalise_email from izi.core.compat import get_user_model from izi.core.loading import get_classes, get_model from izi.views import sort_queryset User = get_user_model() Partner = get_model('partner', 'Partner') (PartnerSearchForm, PartnerCreateForm, PartnerAddressForm, NewUserForm, UserEmailForm, ExistingUserForm) = get_classes('dashboard.partners.forms', [ 'PartnerSearchForm', 'PartnerCreateForm', 'PartnerAddressForm', 'NewUserForm', 'UserEmailForm', 'ExistingUserForm' ]) class PartnerListView(generic.ListView): model = Partner context_object_name = 'partners' template_name = 'dashboard/partners/partner_list.html' form_class = PartnerSearchForm def get_queryset(self): qs = self.model._default_manager.all() qs = sort_queryset(qs, self.request, ['name']) self.description = _("All partners")
from django.forms.models import inlineformset_factory from izi.core.loading import get_class, get_classes HandPickedProductList, OrderedProduct \ = get_classes('promotions.models', ['HandPickedProductList', 'OrderedProduct']) ProductSelect = get_class('dashboard.catalogue.widgets', 'ProductSelect') OrderedProductForm = get_class('dashboard.promotions.forms', 'OrderedProductForm') OrderedProductFormSet = inlineformset_factory(HandPickedProductList, OrderedProduct, form=OrderedProductForm, extra=2)
from django.contrib import messages from django.contrib.contenttypes.models import ContentType from django.db.models import Count from django.http import HttpResponseRedirect from django.shortcuts import HttpResponse from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.views import generic from izi.apps.promotions.conf import PROMOTION_CLASSES from izi.core.loading import get_class, get_classes SingleProduct, RawHTML, Image, MultiImage, AutomaticProductList, \ PagePromotion, HandPickedProductList \ = get_classes('promotions.models', ['SingleProduct', 'RawHTML', 'Image', 'MultiImage', 'AutomaticProductList', 'PagePromotion', 'HandPickedProductList']) SelectForm, RawHTMLForm, PagePromotionForm, HandPickedProductListForm, \ SingleProductForm \ = get_classes('dashboard.promotions.forms', ['PromotionTypeSelectForm', 'RawHTMLForm', 'PagePromotionForm', 'HandPickedProductListForm', 'SingleProductForm']) OrderedProductFormSet = get_class('dashboard.promotions.formsets', 'OrderedProductFormSet') class ListView(generic.TemplateView): template_name = 'dashboard/promotions/promotion_list.html' def get_context_data(self): # Need to load all promotions of all types and chain them together
from __future__ import unicode_literals from decimal import Decimal as D from django.test import TestCase from django.test.client import Client from django.urls import reverse from django.utils.encoding import force_text from mock import Mock, patch from izi.apps.basket.models import Basket from izi.apps.order.models import Order from izi.core.loading import get_classes from izi.test.factories import create_product from purl import URL Partner, StockRecord = get_classes('partner.models', ('Partner', 'StockRecord')) (ProductClass, Product, ProductAttribute, ProductAttributeValue) = get_classes( 'catalogue.models', ('ProductClass', 'Product', 'ProductAttribute', 'ProductAttributeValue')) class MockedPayPalTests(TestCase): fixtures = ['countries.json'] response_body = None def setUp(self): self.client = Client() with patch('requests.post') as post: self.patch_http_post(post) self.perform_action()
from django.utils import timezone from django.utils.translation import gettext_lazy as _ from django.views.generic import DeleteView, FormView, ListView from izi.core.loading import get_class, get_classes, get_model from izi.views import sort_queryset ConditionalOffer = get_model('offer', 'ConditionalOffer') Condition = get_model('offer', 'Condition') Range = get_model('offer', 'Range') Product = get_model('catalogue', 'Product') OrderDiscount = get_model('order', 'OrderDiscount') Benefit = get_model('offer', 'Benefit') MetaDataForm, ConditionForm, BenefitForm, RestrictionsForm, OfferSearchForm \ = get_classes('dashboard.offers.forms', ['MetaDataForm', 'ConditionForm', 'BenefitForm', 'RestrictionsForm', 'OfferSearchForm']) OrderDiscountCSVFormatter = get_class('dashboard.offers.reports', 'OrderDiscountCSVFormatter') class OfferListView(ListView): model = ConditionalOffer context_object_name = 'offers' template_name = 'dashboard/offers/offer_list.html' form_class = OfferSearchForm paginate_by = settings.IZI_DASHBOARD_ITEMS_PER_PAGE def get_queryset(self): qs = self.model._default_manager.exclude( offer_type=ConditionalOffer.VOUCHER)
from decimal import Decimal as D from django.core.exceptions import ImproperlyConfigured from django.utils.translation import gettext_lazy as _ from izi.core.loading import get_classes (Free, NoShippingRequired, TaxExclusiveOfferDiscount, TaxInclusiveOfferDiscount) \ = get_classes('shipping.methods', ['Free', 'NoShippingRequired', 'TaxExclusiveOfferDiscount', 'TaxInclusiveOfferDiscount']) class Repository(object): """ Repository class responsible for returning ShippingMethod objects for a given user, basket etc """ # We default to just free shipping. Customise this class and override this # property to add your own shipping methods. This should be a list of # instantiated shipping methods. methods = (Free(), ) # API def get_shipping_methods(self, basket, shipping_addr=None, **kwargs): """ Return a list of all applicable shipping method instances for a given basket, address etc. """
from django.conf import settings from django.contrib import messages from django.shortcuts import get_object_or_404, redirect from django.utils.translation import gettext_lazy as _ from django.views.generic import CreateView, DetailView, ListView, View from izi.apps.catalogue.reviews.signals import review_added from izi.core.loading import get_classes, get_model from izi.core.utils import redirect_to_referrer ProductReviewForm, VoteForm, SortReviewsForm = get_classes( 'catalogue.reviews.forms', ['ProductReviewForm', 'VoteForm', 'SortReviewsForm']) Vote = get_model('reviews', 'vote') ProductReview = get_model('reviews', 'ProductReview') Product = get_model('catalogue', 'product') class CreateProductReview(CreateView): template_name = "catalogue/reviews/review_form.html" model = ProductReview product_model = Product form_class = ProductReviewForm view_signal = review_added def dispatch(self, request, *args, **kwargs): self.product = get_object_or_404(self.product_model, pk=kwargs['product_pk']) # check permission to leave review if not self.product.is_review_permitted(request.user):
from django.shortcuts import redirect from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.views.generic import (DeleteView, DetailView, FormView, ListView, UpdateView) from django.views.generic.detail import SingleObjectMixin from django.views.generic.edit import FormMixin from django_tables2 import SingleTableView from izi.apps.customer.utils import normalise_email from izi.core.compat import get_user_model from izi.core.loading import get_class, get_classes, get_model from izi.views.generic import BulkEditMixin UserSearchForm, ProductAlertSearchForm, ProductAlertUpdateForm = get_classes( 'dashboard.users.forms', ('UserSearchForm', 'ProductAlertSearchForm', 'ProductAlertUpdateForm')) PasswordResetForm = get_class('customer.forms', 'PasswordResetForm') UserTable = get_class('dashboard.users.tables', 'UserTable') ProductAlert = get_model('customer', 'ProductAlert') User = get_user_model() class IndexView(BulkEditMixin, FormMixin, SingleTableView): template_name = 'dashboard/users/index.html' table_pagination = True model = User actions = ( 'make_active', 'make_inactive', )
from django.db import models from django.db.models import Sum from django.utils.encoding import smart_text from django.utils.timezone import now from django.utils.translation import gettext_lazy as _ from izi.core.compat import AUTH_USER_MODEL from izi.core.loading import get_class, get_classes from izi.core.utils import get_default_currency from izi.models.fields.slugfield import SlugField from izi.templatetags.currency_filters import currency OfferApplications = get_class('offer.results', 'OfferApplications') Unavailable = get_class('partner.availability', 'Unavailable') LineOfferConsumer = get_class('basket.utils', 'LineOfferConsumer') OpenBasketManager, SavedBasketManager = get_classes( 'basket.managers', ['OpenBasketManager', 'SavedBasketManager']) class AbstractBasket(models.Model): """ Basket object """ # Baskets can be anonymously owned - hence this field is nullable. When a # anon user signs in, their two baskets are merged. owner = models.ForeignKey(AUTH_USER_MODEL, null=True, related_name='baskets', on_delete=models.CASCADE, verbose_name=_("Owner")) # Basket statuses
def test_load_izi_classes_correctly(self): Product, Category = get_classes('catalogue.models', ('Product', 'Category')) self.assertEqual('izi.apps.catalogue.models', Product.__module__) self.assertEqual('izi.apps.catalogue.models', Category.__module__)
import os from decimal import Decimal as D from django.db.transaction import atomic from django.utils.translation import gettext_lazy as _ from izi.core.compat import UnicodeCSVReader from izi.core.loading import get_class, get_classes ImportingError = get_class('partner.exceptions', 'ImportingError') Partner, StockRecord = get_classes('partner.models', ['Partner', 'StockRecord']) ProductClass, Product, Category, ProductCategory = get_classes( 'catalogue.models', ('ProductClass', 'Product', 'Category', 'ProductCategory')) create_from_breadcrumbs = get_class('catalogue.categories', 'create_from_breadcrumbs') class CatalogueImporter(object): """ CSV product importer used to built sandbox. Might not work very well for anything else. """ _flush = False def __init__(self, logger, delimiter=",", flush=False): self.logger = logger self._delimiter = delimiter self._flush = flush
def test_raise_exception_when_bad_appname_used(self): with self.assertRaises(AppNotFoundError): get_classes('fridge.models', ('Product', 'Category'))
from decimal import Decimal as D from decimal import ROUND_UP from django.utils.translation import gettext_lazy as _ from django.utils.translation import ungettext from izi.core.loading import get_classes, get_model from izi.templatetags.currency_filters import currency Condition = get_model('offer', 'Condition') range_anchor, unit_price = get_classes('offer.utils', ['range_anchor', 'unit_price']) __all__ = ['CountCondition', 'CoverageCondition', 'ValueCondition'] class CountCondition(Condition): """ An offer condition dependent on the NUMBER of matching items from the basket. """ _description = _("Basket includes %(count)d item(s) from %(range)s") @property def name(self): return self._description % { 'count': self.value, 'range': str(self.range).lower() } @property
def test_loading_class_which_is_not_defined_in_local_module(self): with override_settings(INSTALLED_APPS=self.installed_apps): (FixedPrice, ) = get_classes('shipping.methods', ('FixedPrice', )) self.assertEqual('izi.apps.shipping.methods', FixedPrice.__module__)
from django.shortcuts import HttpResponse, get_object_or_404 from django.template.loader import render_to_string from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.utils.translation import ungettext from django.views.generic import (CreateView, DeleteView, ListView, UpdateView, View) from izi.core.loading import get_classes, get_model from izi.views.generic import BulkEditMixin Range = get_model('offer', 'Range') RangeProduct = get_model('offer', 'RangeProduct') RangeProductFileUpload = get_model('offer', 'RangeProductFileUpload') Product = get_model('catalogue', 'Product') RangeForm, RangeProductForm = get_classes('dashboard.ranges.forms', ['RangeForm', 'RangeProductForm']) class RangeListView(ListView): model = Range context_object_name = 'ranges' template_name = 'dashboard/ranges/range_list.html' paginate_by = settings.IZI_DASHBOARD_ITEMS_PER_PAGE class RangeCreateView(CreateView): model = Range template_name = 'dashboard/ranges/range_form.html' form_class = RangeForm def get_success_url(self):
from django.db import models from django.db.models.query import Q from django.template.defaultfilters import date as date_filter from django.urls import reverse from django.utils.functional import cached_property from django.utils.timezone import get_current_timezone, now from django.utils.translation import gettext_lazy as _ from izi.core.compat import AUTH_USER_MODEL from izi.core.decorators import deprecated from izi.core.loading import get_class, get_classes, get_model from izi.models import fields from izi.templatetags.currency_filters import currency ActiveOfferManager, BrowsableRangeManager \ = get_classes('offer.managers', ['ActiveOfferManager', 'BrowsableRangeManager']) ZERO_DISCOUNT = get_class('offer.results', 'ZERO_DISCOUNT') load_proxy, unit_price = get_classes('offer.utils', ['load_proxy', 'unit_price']) class BaseOfferMixin(models.Model): class Meta: abstract = True def proxy(self): """ Return the proxy model """ klassmap = self.proxy_map # Short-circuit logic if current class is already a proxy class. if self.__class__ in klassmap.values():
from django.template.loader import render_to_string from django.urls import reverse from django.utils.http import is_safe_url from django.utils.translation import gettext_lazy as _ from django.views.generic import FormView, View from extra_views import ModelFormSetView from izi.apps.basket.signals import ( basket_addition, voucher_addition, voucher_removal) from izi.core import ajax from izi.core.loading import get_class, get_classes, get_model from izi.core.utils import redirect_to_referrer, safe_referrer Applicator = get_class('offer.applicator', 'Applicator') (BasketLineForm, AddToBasketForm, BasketVoucherForm, SavedLineForm) = get_classes( 'basket.forms', ('BasketLineForm', 'AddToBasketForm', 'BasketVoucherForm', 'SavedLineForm')) BasketLineFormSet, SavedLineFormSet = get_classes( 'basket.formsets', ('BasketLineFormSet', 'SavedLineFormSet')) Repository = get_class('shipping.repository', 'Repository') OrderTotalCalculator = get_class( 'checkout.calculators', 'OrderTotalCalculator') BasketMessageGenerator = get_class('basket.utils', 'BasketMessageGenerator') class BasketView(ModelFormSetView): model = get_model('basket', 'Line') basket_model = get_model('basket', 'Basket') formset_class = BasketLineFormSet form_class = BasketLineForm
from django.db.models.signals import post_save from django.dispatch import receiver from izi.core.loading import get_classes StockRecord, StockAlert = get_classes('partner.models', ['StockRecord', 'StockAlert']) @receiver(post_save, sender=StockRecord) def update_stock_alerts(sender, instance, created, **kwargs): """ Update low-stock alerts """ if created or kwargs.get('raw', False): return stockrecord = instance try: alert = StockAlert.objects.get(stockrecord=stockrecord, status=StockAlert.OPEN) except StockAlert.DoesNotExist: alert = None if stockrecord.is_below_threshold and not alert: StockAlert.objects.create(stockrecord=stockrecord, threshold=stockrecord.low_stock_threshold) elif not stockrecord.is_below_threshold and alert: alert.close()
from django.contrib import messages from django.core.exceptions import ValidationError from django.http import HttpResponseRedirect from django.template.loader import render_to_string from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.views import generic from django.views.generic import ListView from izi.core.loading import get_classes, get_model from izi.core.utils import slugify from izi.core.validators import URLDoesNotExistValidator FlatPage = get_model('flatpages', 'FlatPage') Site = get_model('sites', 'Site') PageSearchForm, PageUpdateForm = get_classes( 'dashboard.pages.forms', ('PageSearchForm', 'PageUpdateForm')) class PageListView(ListView): """ View for listing all existing flatpages. """ template_name = 'dashboard/pages/index.html' model = FlatPage form_class = PageSearchForm paginate_by = settings.IZI_DASHBOARD_ITEMS_PER_PAGE desc_template = '%(main_filter)s %(title_filter)s' def get_queryset(self): """ Get queryset of all flatpages to be displayed. If a
from django.test.utils import override_settings from django.conf import settings from django.urls import clear_url_caches, reverse from django.utils.http import urlquote from izi.core.compat import get_user_model from izi.core.loading import get_class, get_classes, get_model from izi.apps.shipping import methods from izi.test.testcases import WebTestCase from izi.test import factories from . import CheckoutMixin GatewayForm = get_class('checkout.forms', 'GatewayForm') CheckoutSessionData = get_class('checkout.utils', 'CheckoutSessionData') RedirectRequired, UnableToTakePayment, PaymentError = get_classes( 'payment.exceptions', ['RedirectRequired', 'UnableToTakePayment', 'PaymentError']) UnableToPlaceOrder = get_class('order.exceptions', 'UnableToPlaceOrder') Basket = get_model('basket', 'Basket') Order = get_model('order', 'Order') User = get_user_model() # Python 3 compat try: from imp import reload except ImportError: pass def reload_url_conf():
from django import shortcuts from django.contrib import messages from django.template.loader import render_to_string from django.urls import reverse from django.views import generic from izi.core.loading import get_classes, get_model WeightBandForm, WeightBasedForm = get_classes( 'dashboard.shipping.forms', ['WeightBandForm', 'WeightBasedForm']) WeightBased = get_model('shipping', 'WeightBased') WeightBand = get_model('shipping', 'WeightBand') class WeightBasedListView(generic.ListView): model = WeightBased template_name = "dashboard/shipping/weight_based_list.html" context_object_name = "methods" class WeightBasedCreateView(generic.CreateView): model = WeightBased form_class = WeightBasedForm template_name = "dashboard/shipping/weight_based_form.html" def get_success_url(self): msg = render_to_string( 'dashboard/shipping/messages/method_created.html', {'method': self.object}) messages.success(self.request, msg, extra_tags='safe noicon') return reverse('dashboard:shipping-method-detail',