def proxy_map(self): return { self.COUNT: get_class( 'offer.conditions', 'CountCondition'), self.VALUE: get_class( 'offer.conditions', 'ValueCondition'), self.COVERAGE: get_class( 'offer.conditions', 'CoverageCondition'), }
class VoucherDashboardApplication(DashboardApplication): name = None default_permissions = [ 'is_staff', ] list_view = get_class('dashboard.vouchers.views', 'VoucherListView') create_view = get_class('dashboard.vouchers.views', 'VoucherCreateView') update_view = get_class('dashboard.vouchers.views', 'VoucherUpdateView') delete_view = get_class('dashboard.vouchers.views', 'VoucherDeleteView') stats_view = get_class('dashboard.vouchers.views', 'VoucherStatsView') set_list_view = get_class('dashboard.vouchers.views', 'VoucherSetListView') set_create_view = get_class('dashboard.vouchers.views', 'VoucherSetCreateView') set_update_view = get_class('dashboard.vouchers.views', 'VoucherSetUpdateView') set_detail_view = get_class('dashboard.vouchers.views', 'VoucherSetDetailView') set_download_view = get_class('dashboard.vouchers.views', 'VoucherSetDownloadView') def get_urls(self): urls = [ url(r'^$', self.list_view.as_view(), name='voucher-list'), url(r'^create/$', self.create_view.as_view(), name='voucher-create'), url(r'^update/(?P<pk>\d+)/$', self.update_view.as_view(), name='voucher-update'), url(r'^delete/(?P<pk>\d+)/$', self.delete_view.as_view(), name='voucher-delete'), url(r'^stats/(?P<pk>\d+)/$', self.stats_view.as_view(), name='voucher-stats'), url(r'^sets$', self.set_list_view.as_view(), name='voucher-set-list'), url(r'^sets/create/$', self.set_create_view.as_view(), name='voucher-set-create'), url(r'^sets/update/(?P<pk>\d+)/$', self.set_update_view.as_view(), name='voucher-set-update'), url(r'^sets/(?P<pk>\d+)/$', self.set_detail_view.as_view(), name='voucher-set'), url(r'^sets/(?P<pk>\d+)/download$', self.set_download_view.as_view(), name='voucher-set-download'), ] return self.post_process_urls(urls)
def test_raise_importerror_if_app_raises_importerror(self): """ This tests that IZI doesn't fall back to using the IZI catalogue app if the overriding app throws an ImportError. """ apps = list(settings.INSTALLED_APPS) apps[apps.index('tests._site.apps.catalogue' )] = 'tests._site.import_error_app.catalogue' with override_settings(INSTALLED_APPS=apps): with self.assertRaises(ImportError): get_class('catalogue.app', 'CatalogueApplication')
class OfferApplication(Application): name = 'offer' detail_view = get_class('offer.views', 'OfferDetailView') list_view = get_class('offer.views', 'OfferListView') def get_urls(self): urls = [ url(r'^$', self.list_view.as_view(), name='list'), url(r'^(?P<slug>[\w-]+)/$', self.detail_view.as_view(), name='detail'), ] return self.post_process_urls(urls)
class Shop(Application): name = None catalogue_app = get_class('catalogue.app', 'application') customer_app = get_class('customer.app', 'application') basket_app = get_class('basket.app', 'application') checkout_app = get_class('checkout.app', 'application') promotions_app = get_class('promotions.app', 'application') search_app = get_class('search.app', 'application') dashboard_app = get_class('dashboard.app', 'application') offer_app = get_class('offer.app', 'application') password_reset_form = get_class('customer.forms', 'PasswordResetForm') set_password_form = SetPasswordForm def get_urls(self): urls = [ url(r'^catalogue/', self.catalogue_app.urls), url(r'^basket/', self.basket_app.urls), url(r'^checkout/', self.checkout_app.urls), url(r'^accounts/', self.customer_app.urls), url(r'^search/', self.search_app.urls), url(r'^dashboard/', self.dashboard_app.urls), url(r'^offers/', self.offer_app.urls), # Password reset - as we're using Django's default view functions, # we can't namespace these urls as that prevents # the reverse function from working. url(r'^password-reset/$', login_forbidden( auth_views.PasswordResetView.as_view( form_class=self.password_reset_form, success_url=reverse_lazy('password-reset-done'))), name='password-reset'), url(r'^password-reset/done/$', login_forbidden(auth_views.PasswordResetDoneView.as_view()), name='password-reset-done'), url(r'^password-reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$', login_forbidden( auth_views.PasswordResetConfirmView.as_view( form_class=self.set_password_form, success_url=reverse_lazy('password-reset-complete'))), name='password-reset-confirm'), url(r'^password-reset/complete/$', login_forbidden( auth_views.PasswordResetCompleteView.as_view()), name='password-reset-complete'), ] if settings.IZI_PROMOTIONS_ENABLED: urls.append(url(r'', self.promotions_app.urls)) return urls
class CheckoutApplication(Application): name = 'checkout' index_view = get_class('checkout.views', 'IndexView') shipping_address_view = get_class('checkout.views', 'ShippingAddressView') user_address_update_view = get_class('checkout.views', 'UserAddressUpdateView') user_address_delete_view = get_class('checkout.views', 'UserAddressDeleteView') shipping_method_view = get_class('checkout.views', 'ShippingMethodView') payment_method_view = get_class('checkout.views', 'PaymentMethodView') payment_details_view = get_class('checkout.views', 'PaymentDetailsView') thankyou_view = get_class('checkout.views', 'ThankYouView') def get_urls(self): urls = [ url(r'^$', self.index_view.as_view(), name='index'), # Shipping/user address views url(r'shipping-address/$', self.shipping_address_view.as_view(), name='shipping-address'), url(r'user-address/edit/(?P<pk>\d+)/$', self.user_address_update_view.as_view(), name='user-address-update'), url(r'user-address/delete/(?P<pk>\d+)/$', self.user_address_delete_view.as_view(), name='user-address-delete'), # Shipping method views url(r'shipping-method/$', self.shipping_method_view.as_view(), name='shipping-method'), # Payment views url(r'payment-method/$', self.payment_method_view.as_view(), name='payment-method'), url(r'payment-details/$', self.payment_details_view.as_view(), name='payment-details'), # Preview and thankyou url(r'preview/$', self.payment_details_view.as_view(preview=True), name='preview'), url(r'thank-you/$', self.thankyou_view.as_view(), name='thank-you'), ] return self.post_process_urls(urls) def get_url_decorator(self, pattern): if not settings.IZI_ALLOW_ANON_CHECKOUT: return login_required if pattern.name.startswith('user-address'): return login_required return None
class PartnersDashboardApplication(DashboardApplication): name = None default_permissions = [ 'is_staff', ] list_view = get_class('dashboard.partners.views', 'PartnerListView') create_view = get_class('dashboard.partners.views', 'PartnerCreateView') manage_view = get_class('dashboard.partners.views', 'PartnerManageView') delete_view = get_class('dashboard.partners.views', 'PartnerDeleteView') user_link_view = get_class('dashboard.partners.views', 'PartnerUserLinkView') user_unlink_view = get_class('dashboard.partners.views', 'PartnerUserUnlinkView') user_create_view = get_class('dashboard.partners.views', 'PartnerUserCreateView') user_select_view = get_class('dashboard.partners.views', 'PartnerUserSelectView') user_update_view = get_class('dashboard.partners.views', 'PartnerUserUpdateView') def get_urls(self): urls = [ url(r'^$', self.list_view.as_view(), name='partner-list'), url(r'^create/$', self.create_view.as_view(), name='partner-create'), url(r'^(?P<pk>\d+)/$', self.manage_view.as_view(), name='partner-manage'), url(r'^(?P<pk>\d+)/delete/$', self.delete_view.as_view(), name='partner-delete'), url(r'^(?P<partner_pk>\d+)/users/add/$', self.user_create_view.as_view(), name='partner-user-create'), url(r'^(?P<partner_pk>\d+)/users/select/$', self.user_select_view.as_view(), name='partner-user-select'), url(r'^(?P<partner_pk>\d+)/users/(?P<user_pk>\d+)/link/$', self.user_link_view.as_view(), name='partner-user-link'), url(r'^(?P<partner_pk>\d+)/users/(?P<user_pk>\d+)/unlink/$', self.user_unlink_view.as_view(), name='partner-user-unlink'), url(r'^(?P<partner_pk>\d+)/users/(?P<user_pk>\d+)/update/$', self.user_update_view.as_view(), name='partner-user-update'), ] return self.post_process_urls(urls)
class ReviewsApplication(DashboardApplication): name = None default_permissions = ['is_staff', ] list_view = get_class('dashboard.reviews.views', 'ReviewListView') update_view = get_class('dashboard.reviews.views', 'ReviewUpdateView') delete_view = get_class('dashboard.reviews.views', 'ReviewDeleteView') def get_urls(self): urls = [ url(r'^$', self.list_view.as_view(), name='reviews-list'), url(r'^(?P<pk>\d+)/$', self.update_view.as_view(), name='reviews-update'), url(r'^(?P<pk>\d+)/delete/$', self.delete_view.as_view(), name='reviews-delete'), ] return self.post_process_urls(urls)
class CommsDashboardApplication(DashboardApplication): name = None default_permissions = [ 'is_staff', ] list_view = get_class('dashboard.communications.views', 'ListView') update_view = get_class('dashboard.communications.views', 'UpdateView') def get_urls(self): urls = [ url(r'^$', self.list_view.as_view(), name='comms-list'), url(r'^(?P<slug>\w+)/$', self.update_view.as_view(), name='comms-update'), ] return self.post_process_urls(urls)
class PromotionsApplication(Application): name = 'promotions' home_view = get_class('promotions.views', 'HomeView') record_click_view = get_class('promotions.views', 'RecordClickView') def get_urls(self): urls = [ url(r'page-redirect/(?P<page_promotion_id>\d+)/$', self.record_click_view.as_view(model=PagePromotion), name='page-click'), url(r'keyword-redirect/(?P<keyword_promotion_id>\d+)/$', self.record_click_view.as_view(model=KeywordPromotion), name='keyword-click'), url(r'^$', self.home_view.as_view(), name='home'), ] return self.post_process_urls(urls)
def test_override_class_loader(self): # Clear lru cache for the class loader get_class_loader.cache_clear() View = get_class('catalogue.views', 'ProductDetailView') self.assertEqual(View, DummyClass) # Clear lru cache for the class loader again get_class_loader.cache_clear()
def default_access_fn(user, url_name, url_args=None, url_kwargs=None): """ Given a url_name and a user, this function tries to assess whether the user has the right to access the URL. The application instance of the view is fetched via dynamic imports, and those assumptions will only hold true if the standard IZI layout is followed. Once the permissions for the view are known, the access logic used by the dashboard decorator is evaluated This function might seem costly, but a simple comparison with DTT did not show any change in response time """ exception = ImproperlyConfigured( "Please follow IZI's default dashboard app layout or set a " "custom access_fn") if url_name is None: # it's a heading return True # get view module string. try: url = reverse(url_name, args=url_args, kwargs=url_kwargs) except NoReverseMatch: # In IZI 1.5 this exception was silently ignored which made debugging # very difficult. Now it is being logged and in future the exception will # be propagated. logger.exception('Invalid URL name {}'.format(url_name)) return False view_module = resolve(url).func.__module__ # We can't assume that the view has the same parent module as the app, # as either the app or view can be customised. So we turn the module # string (e.g. 'izi.apps.dashboard.catalogue.views') into an app # label that can be loaded by get_class (e.g. # 'dashboard.catalogue.app), which then essentially checks # INSTALLED_APPS for the right module to load match = re.search('(dashboard[\w\.]*)\.views$', view_module) if not match: raise exception app_label_str = match.groups()[0] + '.app' try: app_instance = get_class(app_label_str, 'application') except AppNotFoundError: raise exception # handle name-spaced view names if ':' in url_name: view_name = url_name.split(':')[1] else: view_name = url_name permissions = app_instance.get_permissions(view_name) return check_permissions(user, permissions)
class ReviewsApplication(Application): name = None reviews_app = get_class('catalogue.reviews.app', 'application') def get_urls(self): urlpatterns = super().get_urls() urlpatterns += [ url(r'^(?P<product_slug>[\w-]*)_(?P<product_pk>\d+)/reviews/', self.reviews_app.urls) ] return self.post_process_urls(urlpatterns)
class OrdersDashboardApplication(DashboardApplication): name = None default_permissions = [ 'is_staff', ] permissions_map = { 'order-list': (['is_staff'], ['partner.dashboard_access']), 'order-stats': (['is_staff'], ['partner.dashboard_access']), 'order-detail': (['is_staff'], ['partner.dashboard_access']), 'order-detail-note': (['is_staff'], ['partner.dashboard_access']), 'order-line-detail': (['is_staff'], ['partner.dashboard_access']), 'order-shipping-address': (['is_staff'], ['partner.dashboard_access']), } order_list_view = get_class('dashboard.orders.views', 'OrderListView') order_detail_view = get_class('dashboard.orders.views', 'OrderDetailView') shipping_address_view = get_class('dashboard.orders.views', 'ShippingAddressUpdateView') line_detail_view = get_class('dashboard.orders.views', 'LineDetailView') order_stats_view = get_class('dashboard.orders.views', 'OrderStatsView') def get_urls(self): urls = [ url(r'^$', self.order_list_view.as_view(), name='order-list'), url(r'^statistics/$', self.order_stats_view.as_view(), name='order-stats'), url(r'^(?P<number>[-\w]+)/$', self.order_detail_view.as_view(), name='order-detail'), url(r'^(?P<number>[-\w]+)/notes/(?P<note_id>\d+)/$', self.order_detail_view.as_view(), name='order-detail-note'), url(r'^(?P<number>[-\w]+)/lines/(?P<line_id>\d+)/$', self.line_detail_view.as_view(), name='order-line-detail'), url(r'^(?P<number>[-\w]+)/shipping-address/$', self.shipping_address_view.as_view(), name='order-shipping-address'), ] return self.post_process_urls(urls)
def get_product_search_handler_class(): """ Determine the search handler to use. Currently only Solr is supported as a search backend, so it falls back to rudimentary category browsing if that isn't enabled. """ # Use get_class to ensure overridability if settings.IZI_PRODUCT_SEARCH_HANDLER is not None: return import_string(settings.IZI_PRODUCT_SEARCH_HANDLER) if is_solr_supported(): return get_class('catalogue.search_handlers', 'SolrProductSearchHandler') elif is_elasticsearch_supported(): return get_class( 'catalogue.search_handlers', 'ESProductSearchHandler', ) else: return get_class('catalogue.search_handlers', 'SimpleProductSearchHandler')
class ProductReviewsApplication(Application): name = None hidable_feature_name = "reviews" detail_view = get_class('catalogue.reviews.views', 'ProductReviewDetail') create_view = get_class('catalogue.reviews.views', 'CreateProductReview') vote_view = get_class('catalogue.reviews.views', 'AddVoteView') list_view = get_class('catalogue.reviews.views', 'ProductReviewList') def get_urls(self): urls = [ url(r'^(?P<pk>\d+)/$', self.detail_view.as_view(), name='reviews-detail'), url(r'^add/$', self.create_view.as_view(), name='reviews-add'), url(r'^(?P<pk>\d+)/vote/$', login_required(self.vote_view.as_view()), name='reviews-vote'), url(r'^$', self.list_view.as_view(), name='reviews-list'), ] return self.post_process_urls(urls)
class RangeDashboardApplication(DashboardApplication): name = None default_permissions = [ 'is_staff', ] list_view = get_class('dashboard.ranges.views', 'RangeListView') create_view = get_class('dashboard.ranges.views', 'RangeCreateView') update_view = get_class('dashboard.ranges.views', 'RangeUpdateView') delete_view = get_class('dashboard.ranges.views', 'RangeDeleteView') products_view = get_class('dashboard.ranges.views', 'RangeProductListView') reorder_view = get_class('dashboard.ranges.views', 'RangeReorderView') def get_urls(self): urlpatterns = [ url(r'^$', self.list_view.as_view(), name='range-list'), url(r'^create/$', self.create_view.as_view(), name='range-create'), url(r'^(?P<pk>\d+)/$', self.update_view.as_view(), name='range-update'), url(r'^(?P<pk>\d+)/delete/$', self.delete_view.as_view(), name='range-delete'), url(r'^(?P<pk>\d+)/products/$', self.products_view.as_view(), name='range-products'), url(r'^(?P<pk>\d+)/reorder/$', self.reorder_view.as_view(), name='range-reorder'), ] return self.post_process_urls(urlpatterns)
class BaseCatalogueApplication(Application): name = 'catalogue' detail_view = get_class('catalogue.views', 'ProductDetailView') catalogue_view = get_class('catalogue.views', 'CatalogueView') category_view = get_class('catalogue.views', 'ProductCategoryView') range_view = get_class('offer.views', 'RangeDetailView') def get_urls(self): urlpatterns = super().get_urls() urlpatterns += [ url(r'^$', self.catalogue_view.as_view(), name='index'), url(r'^(?P<product_slug>[\w-]*)_(?P<pk>\d+)/$', self.detail_view.as_view(), name='detail'), url(r'^category/(?P<category_slug>[\w-]+(/[\w-]+)*)_(?P<pk>\d+)/$', self.category_view.as_view(), name='category'), url(r'^ranges/(?P<slug>[\w-]+)/$', self.range_view.as_view(), name='range') ] return self.post_process_urls(urlpatterns)
class FlatPageManagementApplication(DashboardApplication): name = None default_permissions = ['is_staff', ] list_view = get_class('dashboard.pages.views', 'PageListView') create_view = get_class('dashboard.pages.views', 'PageCreateView') update_view = get_class('dashboard.pages.views', 'PageUpdateView') delete_view = get_class('dashboard.pages.views', 'PageDeleteView') def get_urls(self): """ Get URL patterns defined for flatpage management application. """ urls = [ url(r'^$', self.list_view.as_view(), name='page-list'), url(r'^create/$', self.create_view.as_view(), name='page-create'), url(r'^update/(?P<pk>[-\w]+)/$', self.update_view.as_view(), name='page-update'), url(r'^delete/(?P<pk>\d+)/$', self.delete_view.as_view(), name='page-delete') ] return self.post_process_urls(urls)
class ReportsApplication(DashboardApplication): name = None default_permissions = [ 'is_staff', ] index_view = get_class('dashboard.reports.views', 'IndexView') def get_urls(self): urls = [ url(r'^$', self.index_view.as_view(), name='reports-index'), ] return self.post_process_urls(urls)
class BasketApplication(Application): name = 'basket' summary_view = get_class('basket.views', 'BasketView') saved_view = get_class('basket.views', 'SavedView') add_view = get_class('basket.views', 'BasketAddView') add_voucher_view = get_class('basket.views', 'VoucherAddView') remove_voucher_view = get_class('basket.views', 'VoucherRemoveView') def get_urls(self): urls = [ url(r'^$', self.summary_view.as_view(), name='summary'), url(r'^add/(?P<pk>\d+)/$', self.add_view.as_view(), name='add'), url(r'^vouchers/add/$', self.add_voucher_view.as_view(), name='vouchers-add'), url(r'^vouchers/(?P<pk>\d+)/remove/$', self.remove_voucher_view.as_view(), name='vouchers-remove'), url(r'^saved/$', login_required(self.saved_view.as_view()), name='saved'), ] return self.post_process_urls(urls)
class SearchApplication(Application): name = 'search' search_view = get_class('search.views', 'FacetedSearchView') search_form = get_class('search.forms', 'SearchForm') def get_urls(self): # The form class has to be passed to the __init__ method as that is how # Haystack works. It's slightly different to normal CBVs. urlpatterns = [ url(r'^$', search_view_factory( view_class=self.search_view, form_class=self.search_form, searchqueryset=self.get_sqs()), name='search'), ] return self.post_process_urls(urlpatterns) def get_sqs(self): """ Return the SQS required by a the Haystack search view """ return facets.base_sqs()
class PromotionsDashboardApplication(DashboardApplication): name = None default_permissions = ['is_staff', ] list_view = get_class('dashboard.promotions.views', 'ListView') page_list = get_class('dashboard.promotions.views', 'PageListView') page_detail = get_class('dashboard.promotions.views', 'PageDetailView') create_redirect_view = get_class('dashboard.promotions.views', 'CreateRedirectView') delete_page_promotion_view = get_class('dashboard.promotions.views', 'DeletePagePromotionView') # Dynamically set the CRUD views for all promotion classes view_names = ( ('create_%s_view', 'Create%sView'), ('update_%s_view', 'Update%sView'), ('delete_%s_view', 'Delete%sView') ) for klass in PROMOTION_CLASSES: for attr_name, view_name in view_names: full_attr_name = attr_name % klass.classname() full_view_name = view_name % klass.__name__ view = get_class('dashboard.promotions.views', full_view_name) locals()[full_attr_name] = view def get_urls(self): urls = [ url(r'^$', self.list_view.as_view(), name='promotion-list'), url(r'^pages/$', self.page_list.as_view(), name='promotion-list-by-page'), url(r'^page/(?P<path>/([\w-]+(/[\w-]+)*/)?)$', self.page_detail.as_view(), name='promotion-list-by-url'), url(r'^create/$', self.create_redirect_view.as_view(), name='promotion-create-redirect'), url(r'^page-promotion/(?P<pk>\d+)/$', self.delete_page_promotion_view.as_view(), name='pagepromotion-delete')] for klass in PROMOTION_CLASSES: code = klass.classname() urls += [ url(r'create/%s/' % code, getattr(self, 'create_%s_view' % code).as_view(), name='promotion-create-%s' % code), url(r'^update/(?P<ptype>%s)/(?P<pk>\d+)/$' % code, getattr(self, 'update_%s_view' % code).as_view(), name='promotion-update'), url(r'^delete/(?P<ptype>%s)/(?P<pk>\d+)/$' % code, getattr(self, 'delete_%s_view' % code).as_view(), name='promotion-delete')] return self.post_process_urls(urls)
class RequestFactory(BaseRequestFactory): Basket = get_model('basket', 'basket') selector = get_class('partner.strategy', 'Selector')() def request(self, user=None, **request): request = super().request(**request) request.user = user or AnonymousUser() request.session = SessionStore() request._messages = FallbackStorage(request) request.basket = self.Basket() request.basket_hash = None strategy = self.selector.strategy(request=request, user=request.user) request.strategy = request.basket.strategy = strategy return request
class OffersDashboardApplication(DashboardApplication): name = None default_permissions = ['is_staff', ] list_view = get_class('dashboard.offers.views', 'OfferListView') metadata_view = get_class('dashboard.offers.views', 'OfferMetaDataView') condition_view = get_class('dashboard.offers.views', 'OfferConditionView') benefit_view = get_class('dashboard.offers.views', 'OfferBenefitView') restrictions_view = get_class('dashboard.offers.views', 'OfferRestrictionsView') delete_view = get_class('dashboard.offers.views', 'OfferDeleteView') detail_view = get_class('dashboard.offers.views', 'OfferDetailView') def get_urls(self): urls = [ url(r'^$', self.list_view.as_view(), name='offer-list'), # Creation url(r'^new/name-and-description/$', self.metadata_view.as_view(), name='offer-metadata'), url(r'^new/condition/$', self.condition_view.as_view(), name='offer-condition'), url(r'^new/incentive/$', self.benefit_view.as_view(), name='offer-benefit'), url(r'^new/restrictions/$', self.restrictions_view.as_view(), name='offer-restrictions'), # Update url(r'^(?P<pk>\d+)/name-and-description/$', self.metadata_view.as_view(update=True), name='offer-metadata'), url(r'^(?P<pk>\d+)/condition/$', self.condition_view.as_view(update=True), name='offer-condition'), url(r'^(?P<pk>\d+)/incentive/$', self.benefit_view.as_view(update=True), name='offer-benefit'), url(r'^(?P<pk>\d+)/restrictions/$', self.restrictions_view.as_view(update=True), name='offer-restrictions'), # Delete url(r'^(?P<pk>\d+)/delete/$', self.delete_view.as_view(), name='offer-delete'), # Stats url(r'^(?P<pk>\d+)/$', self.detail_view.as_view(), name='offer-detail'), ] return self.post_process_urls(urls)
def proxy_map(self): return { self.PERCENTAGE: get_class( 'offer.benefits', 'PercentageDiscountBenefit'), self.FIXED: get_class( 'offer.benefits', 'AbsoluteDiscountBenefit'), self.MULTIBUY: get_class( 'offer.benefits', 'MultibuyDiscountBenefit'), self.FIXED_PRICE: get_class( 'offer.benefits', 'FixedPriceBenefit'), self.SHIPPING_ABSOLUTE: get_class( 'offer.benefits', 'ShippingAbsoluteDiscountBenefit'), self.SHIPPING_FIXED_PRICE: get_class( 'offer.benefits', 'ShippingFixedPriceBenefit'), self.SHIPPING_PERCENTAGE: get_class( 'offer.benefits', 'ShippingPercentageDiscountBenefit') }
class RequestFactory(BaseRequestFactory): Basket = get_model('basket', 'basket') selector = get_class('partner.strategy', 'Selector')() def request(self, user=None, basket=None, **request): request = super().request(**request) request.user = user or AnonymousUser() request.session = SessionStore() request._messages = FallbackStorage(request) # Mimic basket middleware request.strategy = self.selector.strategy( request=request, user=request.user) request.basket = basket or self.Basket() request.basket.strategy = request.strategy request.basket_hash = Signer().sign(basket.pk) if basket else None request.cookies_to_delete = [] return request
class ShippingDashboardApplication(DashboardApplication): name = None default_permissions = ['is_staff'] weight_method_list_view = get_class('dashboard.shipping.views', 'WeightBasedListView') weight_method_create_view = get_class('dashboard.shipping.views', 'WeightBasedCreateView') weight_method_edit_view = get_class('dashboard.shipping.views', 'WeightBasedUpdateView') weight_method_delete_view = get_class('dashboard.shipping.views', 'WeightBasedDeleteView') # This doubles as the weight_band create view weight_method_detail_view = get_class('dashboard.shipping.views', 'WeightBasedDetailView') weight_band_edit_view = get_class('dashboard.shipping.views', 'WeightBandUpdateView') weight_band_delete_view = get_class('dashboard.shipping.views', 'WeightBandDeleteView') def get_urls(self): urlpatterns = [ url(r'^weight-based/$', self.weight_method_list_view.as_view(), name='shipping-method-list'), url(r'^weight-based/create/$', self.weight_method_create_view.as_view(), name='shipping-method-create'), url(r'^weight-based/(?P<pk>\d+)/$', self.weight_method_detail_view.as_view(), name='shipping-method-detail'), url(r'^weight-based/(?P<pk>\d+)/edit/$', self.weight_method_edit_view.as_view(), name='shipping-method-edit'), url(r'^weight-based/(?P<pk>\d+)/delete/$', self.weight_method_delete_view.as_view(), name='shipping-method-delete'), url(r'^weight-based/(?P<method_pk>\d+)/bands/(?P<pk>\d+)/$', self.weight_band_edit_view.as_view(), name='shipping-method-band-edit'), url(r'^weight-based/(?P<method_pk>\d+)/bands/(?P<pk>\d+)/delete/$', self.weight_band_delete_view.as_view(), name='shipping-method-band-delete'), ] return self.post_process_urls(urlpatterns)
class UserManagementApplication(DashboardApplication): name = None default_permissions = [ 'is_staff', ] index_view = get_class('dashboard.users.views', 'IndexView') user_detail_view = get_class('dashboard.users.views', 'UserDetailView') password_reset_view = get_class('dashboard.users.views', 'PasswordResetView') alert_list_view = get_class('dashboard.users.views', 'ProductAlertListView') alert_update_view = get_class('dashboard.users.views', 'ProductAlertUpdateView') alert_delete_view = get_class('dashboard.users.views', 'ProductAlertDeleteView') def get_urls(self): urls = [ url(r'^$', self.index_view.as_view(), name='users-index'), url(r'^(?P<pk>-?\d+)/$', self.user_detail_view.as_view(), name='user-detail'), url(r'^(?P<pk>-?\d+)/password-reset/$', self.password_reset_view.as_view(), name='user-password-reset'), # Alerts url(r'^alerts/$', self.alert_list_view.as_view(), name='user-alert-list'), url(r'^alerts/(?P<pk>-?\d+)/delete/$', self.alert_delete_view.as_view(), name='user-alert-delete'), url(r'^alerts/(?P<pk>-?\d+)/update/$', self.alert_update_view.as_view(), name='user-alert-update'), ] return self.post_process_urls(urls)
from django.conf import settings from django.utils.module_loading import import_string from django.views.generic.list import MultipleObjectMixin from izi.core.loading import get_class, get_model BrowseCategoryForm = get_class('search.forms', 'BrowseCategoryForm') SearchHandler = get_class('search.search_handlers', 'SearchHandler') is_solr_supported = get_class('search.features', 'is_solr_supported') is_elasticsearch_supported = get_class('search.features', 'is_elasticsearch_supported') Product = get_model('catalogue', 'Product') def get_product_search_handler_class(): """ Determine the search handler to use. Currently only Solr is supported as a search backend, so it falls back to rudimentary category browsing if that isn't enabled. """ # Use get_class to ensure overridability if settings.IZI_PRODUCT_SEARCH_HANDLER is not None: return import_string(settings.IZI_PRODUCT_SEARCH_HANDLER) if is_solr_supported(): return get_class('catalogue.search_handlers', 'SolrProductSearchHandler') elif is_elasticsearch_supported(): return get_class( 'catalogue.search_handlers', 'ESProductSearchHandler',