django-discounts-cart
ΠΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ Django - Π£ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΡΠΊΠΈΠ΄ΠΊΠ°ΠΌΠΈ ΠΈ ΠΊΠΎΡΠ·ΠΈΠ½ΠΎΠΉ Π² ΠΈΠ½ΡΠ΅ΡΠ½Π΅Ρ ΠΌΠ°Π³Π°Π·ΠΈΠ½Π΅.
version 1.1.7
Django >= 1.7 ΠΈ Python 2.7
Π‘ΠΊΠΈΠ΄ΠΊΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡΡΡ ΡΠ΅ΡΠ΅Π· Π°Π΄ΠΌΠΈΠ½-ΠΏΠ°Π½Π΅Π»Ρ.
Π‘ΠΊΠΈΠ΄ΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ΄Π΅Ρ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π½Π° ΠΊΠ°ΠΆΠ΄ΡΡ ΠΊΠ°ΡΠ΅Π³ΠΎΡΠΈΡ ΠΈ ΠΏΡΠΎΠ΄ΡΠΊΡ.
Π’Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΡΡΡΠΎΠΈΡΡ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΡΠΊΠΈΠ΄ΠΎΠΊ.
Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ°:
1) pip install django-discounts-cart 2) ΠΠΎΠ±Π°Π²ΡΡΠ΅ Π² INSTALLED_APPS 'discounts_cart', 3) ΠΠΎΠ±Π°Π²ΡΡΠ΅ Π² context_processors 'discounts_cart.context_processors.vars_cart', 4) ΠΠΎΠ±Π°Π²ΡΡΠ΅ discounts-cart Π² urls.py Π²Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ° url(r'^cart/', include('discounts_cart.urls', namespace='discounts_cart')), 5) ΠΠΎΠ±Π°Π²ΡΡΠ΅ Π² ΠΏΡΠΎΠ΅ΠΊΡ jquery.cookie.js --> http://plugins.jquery.com/cookie/ cart.js --> https://github.com/genkosta/django-discounts-cart/blob/master/cart.js templates/discounts_cart/in_cart_link.html --> https://github.com/genkosta/django-discounts-cart/tree/master/templates/discounts_cart 6) ΠΠ±Π½ΠΎΠ²ΠΈΡΡ ΠΌΠΈΠ³ΡΠ°ΡΠΈΠΈ python manage.py migrate discounts_cart
Π ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ Π΄Π»Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠΈΠΏΠ° ΡΠΎΠ²Π°ΡΠ°, ΡΠΎΠ·Π΄Π°Π΅ΠΌ ΠΌΠΎΠ΄Π΅Π»ΠΈ
Π ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡΡ Π½Π΅ Π·Π°Π±ΡΠ²Π°Π΅ΠΌ Π½Π°ΡΡΡΠ°ΠΈΠ²Π°ΡΡ __init__.py ΠΈ apps.py ΠΡΠΈΠΌΠ΅Ρ: __init__.py default_app_config = 'products.apps.ProductsConfig' apps.py from django.apps import AppConfig class ProductsConfig(AppConfig): name = 'products' verbose_name = 'Products' ΠΡΠΈΠΌΠ΅Ρ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ: ( Π΄Π»Ρ ΠΏΡΠΈΠΌΠ΅ΡΠ°, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡΡΠ΅ΡΡ Π·Π΄Π΅ΡΡ --> https://github.com/genkosta/django-discounts-cart/tree/master/examples ) from django.db import models from discounts_cart.models import DiscountsInCategories, DiscountsInProducts class Brand(DiscountsInCategories): pass class Category(DiscountsInCategories): pass class Parameter(DiscountsInCategories): pass # Product - ΠΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎΠ΅ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΠΌΠΎΠ΄Π΅Π»ΠΈ, Π²ΠΎ Π²ΡΠ΅Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡΡ ΡΠΎΠ²Π°ΡΠΎΠ² class Product(DiscountsInProducts): brand = models.ForeignKey(Brand) categories = models.ManyToManyField(Category) parameters = models.ManyToManyField(Parameter) # ΠΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ def view_price(self): pattern = re.compile(r'\.[0]+$') return '{0} {1}'.format(pattern.sub('', str(self.price)), self.currency) view_price.short_description = _('Price') # ΠΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ @property def get_correct_price(self): return self.price # Only Decimal type # Add names of fields to calculate discounts # ΠΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ @staticmethod def get_field_names(): field_names_dect = { 'foreign_key': ('brand',), 'many_to_many': ('categories', 'parameters') } return field_names_dect
ΠΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ Π² ΡΠ°Π±Π»ΠΎΠ½Ρ
base.html
<!-- Cart --> <div id="id_cart"> <div><strong>Cart</strong></div> <span>count:</span> <span class="cart_count">{{ cart_count }}</span><br> <span>amount:</span> <span class="cart_amount">{{ cart_amount }}</span><br> {% url 'discounts_cart:view_cart' as cart_url %} <a href="{% if cart_count %}{{ cart_url }}{% else %}javascript:void(0);{% endif %}" class="cart_view_product_list" data-cart_url="{{ cart_url }}"> <img src="{% static 'img/cart.png' %}"><br><span>Open</span></a> </div> <a href="{% url 'home' %}">Home</a>  <a href="{% url 'home' %}?sort_by_optimal_discount=1">Sort by optimal discount</a>
home.html
{% extends 'base.html' %} {% load staticfiles discounts_cart %} {% block content %} <!-- View products --> {% for product in products %} <div> <p> Product: {{ product.name }}<br> Discount {{ product.view_optimal_discount }}<br> Price: {{ product.view_price }} < > {{ product.view_optimal_price }} {{ product.currency }} </p> {% cart_add_select_product 'products' 'product' product.id 'In cart' 'From cart' flag_img=True %} </div> <br> {% endfor %} <!-- ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΡΠ΅ Π²Π°ΡΠΈΠ°Π½ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΡΠ°Π±Π»ΠΎΠ½Π½ΠΎΠ³ΠΎ ΡΠ΅Π³Π° cart_add_select_prod --> {% comment %} {% cart_add_select_product 'app' 'model' prod_id 'In cart' 'From cart' %} or {% cart_add_select_product 'app' 'model' prod_id 'In cart' 'From cart' flag_img=True %} or {% cart_add_select_product 'app' 'model' prod_id flag_img=True %} <!-- only images --> {% endcomment %} <!-- README ΠΡΠ³ΡΠΌΠ΅Π½ΡΡ Π΄Π»Ρ ΡΠ°Π±Π»ΠΎΠ½Π½ΠΎΠ³ΠΎ ΡΠ΅Π³Π° - cart_add_select_prod_*: 1) app - ( ΠΈΠΌΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ) 2) model - ( ΠΊΠ»Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ ) 3) prod_id - ( ID ΡΠΎΠ²Π°ΡΠ° - ΠΡΠΈΠΌΠ΅Ρ: product.id) 4) name_in_cart default='' - ( ΠΠ°Π·Π²Π°Π½ΠΈΠ΅ ΡΡΡΠ»ΠΎΠΊ ΠΈΠ»ΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ - ΠΡΠΈΠΌΠ΅Ρ: 'In cart' ) 5) name_from_cart default='' - ( ΠΠ°Π·Π²Π°Π½ΠΈΠ΅ ΡΡΡΠ»ΠΎΠΊ ΠΈΠ»ΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ - ΠΡΠΈΠΌΠ΅Ρ: 'From cart' ) 6) add_more_name default='Add more' - ( ΠΠ°Π·Π²Π°Π½ΠΈΠ΅ ΡΡΡΠ»ΠΎΠΊ Π΄Π»Ρ ΡΠ²Π΅Π»ΠΈΡΠ΅Π½ΠΈΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π° ΡΠΎΠ³ΠΎ ΠΆΠ΅ ΠΏΡΠΎΠ΄ΡΠΊΡΠ° ) 7) flag_img - default=False - ( Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΈΠΉ ΡΠ»Π°Π³, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°ΡΡ ΠΈΠΊΠΎΠ½ΠΊΠΈ Π½Π° ΡΡΡΠ»ΠΊΠ°Ρ ΠΈΠ»ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ°Ρ , Π½Π°ΡΡΡΠΎΠΉΠΊΠ° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ ΡΠ΅ΡΠ΅Π· ΠΊΠ»Π°ΡΡΡ - cart_img_in, cart_img_from ) Classes ( Π΄Π»Ρ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ Π²Π½Π΅ΡΠ½Π΅Π³ΠΎ Π²ΠΈΠ΄Π°, ΡΡΡΠ»ΠΎΠΊ ΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ - 'In cart' ΠΈ 'From cart' ): 1) cart_controls - ( ΠΎΠ±Π΅ΡΡΠΊΠ° <div> Π΄Π»Ρ ΡΡΡΠ»ΠΎΠΊ ΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ ) 2) cart_item_select_product - ( Π΄Π»Ρ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ ΡΡΡΠ»ΠΎΠΊ ΠΈ ΠΊΠ½ΠΎΠΏΠΎΠΊ - 'In cart' ΠΈ 'From cart' ) 3) cart_img_in, cart_img_from - ( Π΄Π»Ρ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ ΠΈΠΊΠΎΠ½ΠΎΠΊ Π½Π° ΡΡΡΠ»ΠΊΠ°Ρ ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ°Ρ , Π΅ΡΠ»ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ flag_img=True ) CSS: <style type="text/css"> .cart_add_more_product { // ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π² ΡΡΠΈΠ»ΠΈ <<< display: none; } .cart_add_more_product_active { // ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π² ΡΡΠΈΠ»ΠΈ <<< display: block; } // ΠΠΎΠ±Π°Π²ΠΈΡΡ Π΅ΡΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ flag_img=True .cart_img_in, .cart_img_from { display: block; width: 40px; height: 40px; background-size: cover; } .cart_img_in { background: url("../img/in_cart.png") no-repeat center; // Π΄ΠΎΠ±Π°Π²ΡΡΠ΅ ΡΠ²ΠΎΡ ΠΈΠΊΠΎΠ½ΠΊΡ } .cart_img_from { background: url("../img/from_cart.png") no-repeat center; // Π΄ΠΎΠ±Π°Π²ΡΡΠ΅ ΡΠ²ΠΎΡ ΠΈΠΊΠΎΠ½ΠΊΡ } </style> --> {% endblock %}
cart.html
{% extends 'base.html' %} {% load staticfiles %} {% block content %} <!-- Products list --> {% for product in products %} <p> Product: {{ product.name }}<br> Count: {{ product.count }}<br> Price: {{ product.view_optimal_price }} {{ product.currency }} </p> {% endfor %} <p>_ _ _ _ _ _ _ _ _ _</p> <!-- Total amount --> <p>ΠΡΠΎΠ³ΠΎ</p> <p>Total count: <span class="cart_count">{{ cart_count }}</span></p> <p>Total amount: <span class="cart_amount">{{ cart_amount }}</span></p> {% if cart_count %} <p>_ _ _ _ _ _ _ _ _ _</p> <!-- Recalculate with a promo-code --> <P>ΠΠ΅ΡΠ΅ΡΡΠΈΡΠ°ΡΡ Ρ ΠΏΡΠΎΠΌΠΎ-ΠΊΠΎΠ΄ΠΎΠΌ</P> <p>Total count: <span class="cart_count_recalculation">0</span></p> <p>Total amount: <span class="cart_amount_recalculation">0</span></p> <form id="id_cart_check_promo_code_form" action="{% url 'discounts_cart:recalculation_cart_with_promo_code' %}" method="post"> <input id="id_cart_promo_code_text" type="text" name="promo_code" value="" placeholder="Enter promo-code"> <button>Recalculation</button> </form> <p>_ _ _ _ _ _ _ _ _ _</p> <!-- Payment --> <p>ΠΠ»Π°ΡΠ΅ΠΆ</p> <form id="id_cart_payment_form" action="{% url 'payments' %}" method="post">{% csrf_token %} <input id="id_cart_promo_code_text" type="text" name="promo_code" value="" placeholder="Enter promo-code, if present"> <button>Payment</button><br> <label for="id_cart_promo_code_text">( ΠΡΠ»ΠΈ ΠΏΡΠΎΠΌΠΎ-ΠΊΠΎΠ΄ Π½Π΅ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΠΈΡ, ΠΎΠ½ Π±ΡΠ΄Π΅Ρ Π½Π΅ ΡΡΡΠ΅Π½. )</label> </form> {% endif %} {% endblock %}
ΠΠ»Ρ ΡΠΎΡΡΠΈΡΠΎΠ²ΠΊΠΈ ΠΏΠΎ ΠΎΠΏΡΠΈΠΌΠ°Π»ΡΠ½ΡΠΌ ΡΠΊΠΈΠ΄ΠΊΠ°ΠΌ
ΠΡΠΈΠΌΠ΅Ρ: home views.py from products.models import Product # ΠΈΠ»ΠΈ Phone ΠΈΠ»ΠΈ Π‘ΡΠΈΡΠ°Π»ΡΠ½ΡΠ΅ ΠΌΠ°ΡΠΈΠ½Ρ def home(request): if request.GET.get('sort_by_optimal_discount', False): # ΠΡΠ±ΠΎΡΠΊΠ° Π²ΡΠ΅Ρ Π°ΠΊΡΠΈΠ²Π½ΡΡ , ΠΏΠ»ΡΡ ΡΠΎΡΡΠΈΡΠΎΠ²ΠΊΠ° ΠΏΠΎ ΠΎΠΏΡΠΈΠΌΠ°Π»ΡΠ½ΡΠΌ ΡΠΊΠΈΠ΄ΠΊΠ°ΠΌ products = Product.products.sort_by_optimal_discount() else: # ΠΡΠ±ΠΎΡΠΊΠ° Π²ΡΠ΅Ρ Π°ΠΊΡΠΈΠ²Π½ΡΡ products = Product.products.active() # ΠΈΠ»ΠΈ # products = Product.objects.filter(active=True) return render(request, 'home.html', { 'products': products })
ΠΠ»Ρ ΠΊΠΎΠ½ΡΡΠΎΠ»Ρ Π½Π°Π΄ ΡΠΊΠΈΠ΄ΠΊΠ°ΠΌΠΈ, ΠΏΠΎΡΠ»Π΅ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ ΠΎΠΏΠ»Π°ΡΡ, Π΄ΠΎΠ±Π°Π²ΠΈΡΡ
( ΠΡΠ»ΠΈ ΠΏΡΠΎΠΌΠΎ-ΠΊΠΎΠ΄Ρ Π½Π°ΡΡΡΠΎΠ΅Π½Ρ ΠΊΠ°ΠΊ ΡΠ΄Π°Π»ΡΠ΅ΠΌΡΠ΅, ΠΎΠ½ΠΈ Π±ΡΠ΄ΡΡ ΡΠ΄Π°Π»ΡΡΡΡ. )
ΠΡΠΈΠΌΠ΅Ρ: payment views.py from discounts_cart.utils import control_promo_codes, recalculation_payment def payment(request): if request.method == 'POST': # Recalculation before payment ( for checking ) result = recalculation_payment(request) count_products = result['count'] amount = result['amount'] # Control promo-codes promo_code = request.POST['promo_code'].strip() control_promo_codes(request, promo_code)
Cron
( ΠΠΎ ΠΆΠ΅Π»Π°Π½ΠΈΡ, Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΠΊΠΎΠΌΠΌΠ°Π½Π΄Ρ Π² Cron. )
# ΠΠ΅Π°ΠΊΡΠΈΠ²ΠΈΡΠΎΠ²Π°ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Π½ΡΠ΅ ΡΠΊΠΈΠ΄ΠΊΠΈ python manage.py discounts_cart deact ΠΈΠ»ΠΈ # Π£Π΄Π°Π»ΠΈΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Π½ΡΠ΅ ΡΠΊΠΈΠ΄ΠΊΠΈ python manage.py discounts_cart del