basket = Basket.objects.filter(user=request.user, book=book).first()
if not basket:
basket = Basket(user=request.user, book=book)
basket.quantity += 1
basket.save()
from collections import UserDict
from core.models import ProductOption, Product
from .models import Item
class Basket(UserDict):
changed = False
def add(self, quantity=0, option=None, set_=False):
self.changed = True
id_ = str(option.product.id)
option = str(option.id)
self.setdefault(id_, {})
self[id_].setdefault(option, 0)
if set_:
self[id_][option] = quantity
else:
self[id_][option] += quantity
if self[id_][option] <= 0:
del self[id_][option]
if not self[id_]:
del self[id_]
return 0
else:
return self[id_][option]
@property
def total_count(self):
return sum(x for product, options in self.items() for _, x in options.items())
@property
def total_price(self):
prices = {str(id_): price for id_, price in
Product.objects.filter(id__in=self.keys()).values_list('id', 'price')}
return sum(x * prices[product] for product, options in self.items() for _, x in options.items())
def cost(self, option):
price = option.product.price
return self.count_option(option) * price
def count_option(self, option):
product_id = str(option.product.id)
option_id = str(option.id)
return self.get(product_id, {}).get(option_id, 0)
def flush(self):
self.changed = True
for key in list(self):
del self[key]
def build_order(self, order):
items = []
for product_id, data in self.items():
product = Product.objects.get(id=product_id)
for option_id, quantity in data.items():
if quantity == 0:
continue
option = None
if option_id != '0':
option = ProductOption.objects.get(id=option_id)
items.append(
Item(order=order, option=option, quantity=quantity, product=product)
)
order.items.bulk_create(items)
self.flush()
return order
def fix(self):
"""Фиксит корзину на случай, если опции удалили, а они находятся в корзине"""
ids = self.keys()
exist_in_db = (Product.objects
.filter(id__in=ids, options__in_stock=True, options__show=True)
.values_list('id', flat=True))
to_remove = set(ids) - set(str(x) for x in exist_in_db)
for id_ in to_remove:
del self[id_]
if to_remove:
self.changed = True
def to_dict(self):
return dict(self)
from django.utils.deprecation import MiddlewareMixin
from .basket import Basket
class BasketMiddleware(MiddlewareMixin):
def process_request(self, request):
request.basket = Basket(request.session.get('basket', {}))
def process_response(self, request, response):
if getattr(request, 'basket', None) is None:
return response
if request.basket.changed:
request.session['basket'] = request.basket.to_dict()
request.session.save()
return response
# ...
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
MIDDLEWARE_CLASSES = [
# ...
'orders.middleware.BasketMiddleware',
]
# ...
@method_decorator(csrf_exempt, name='dispatch')
class ChangeBasketOption(View):
def post(self, request):
change = int(request.POST.get('change'))
pk = int(request.POST.get('id'))
set_ = bool(request.POST.get('set', 0))
option = get_object_or_404(ProductOption, pk=pk)
value = request.basket.add(option=option, quantity=change, set_=set_)
cost = request.basket.cost(option)
return JsonResponse({
'value': value,
'cost': cost,
'total': request.basket.total_price
})
class Basket(FormView):
template_name = 'orders/basket.html'
form_class = OrderForm
success_url = reverse_lazy('ordered')
def get(self, request, *args, **kwargs):
request.basket.fix()
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
kwargs['products'] = Product.objects.filter(id__in=self.request.basket.keys())
kwargs['can_order'] = self.request.basket.total_price >= min_order_cost()
return super().get_context_data(**kwargs)
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
def form_valid(self, form):
order = form.save()
order = self.request.basket.build_order(order)
mail_new_order(order)
return super().form_valid(form)
def first(d):
return next(iter(d.values() if d else []), None)
value = first(first(a))
Есть ли связь между PHP и системным администрированием?нет
Отличное знание WinForms, ASP.NET, LINQ и WPF. Паттерны: MVVM, MVP, Repository, IoC.
Занимался исправлением мелких багов, написанием небольших SQL-запросов и unit-тестов, решал небольшие задачи.
Если вспомнить css и html
foreach (var newOrder in newOrders)
{
// ищем минимальное количество заявок среди всех менеджеров
var minOrdersCount = managers.Min(m => m.Orders.Count);
// ищем менеджера с найденным количеством (если несколько - берём первого)
var manager = managers.First(m => m.Orders.Count == minOrdersCount);
// даём заявку менее занятому менеджеру
manager.Orders.Add(newOrder);
}
class Manager
{
public string Name { get; private set; }
public List<int> Orders { get; private set; }
public Manager(string name, int ordersCount = 0)
{
Name = name;
Orders = ordersCount > 0
? Enumerable.Range(1, ordersCount).ToList()
: new List<int>();
}
}
static void Main(string[] args)
{
var managers = new Manager[]
{
new Manager("Лена", 1),
new Manager("Оля", 10),
new Manager("Иван", 35),
new Manager("Сергей", 75),
};
var newOrders = Enumerable.Range(1, 35).ToList();
var newOrdersCount = newOrders.Count;
var ordersAssigned = 0;
while (ordersAssigned < newOrdersCount)
{
var ordersCounts = managers.Select(m => m.Orders.Count).OrderBy(count => count).Distinct().ToArray();
var addingOrdersCount = ordersCounts.Length > 1 ? ordersCounts[1] - ordersCounts[0] : ordersCounts.First();
var managersWithMinOrders = managers.Where(m => m.Orders.Count == ordersCounts[0]).ToArray();
// нашли менеджеров с минимальным количеством заявок
if (managersWithMinOrders.Length * addingOrdersCount < newOrdersCount)
{ // заполняем самых незанятых менеджеров до того же уровня занятости
// т.е. добавляем Лене (10 - 1) = 9 заявок
foreach (var manager in managersWithMinOrders)
{
for (int i = 0; i < addingOrdersCount; i++)
{
manager.Orders.Add(newOrders[ordersAssigned]);
ordersAssigned++;
}
}
}
else
{
// незанятых менеджеров нет, заполняем оставшиеся заявки по менеджерам по очереди
while (ordersAssigned < newOrdersCount)
{
var managerIndex = ordersAssigned % managersWithMinOrders.Length;
managersWithMinOrders[managerIndex].Orders.Add(newOrders[ordersAssigned]);
ordersAssigned++;
}
}
}
foreach (var manager in managers)
{
Console.WriteLine("{0}: {1} заявок", manager.Name, manager.Orders.Count);
}
Console.ReadKey();
}
data=[4, 5, 7, 8, 9, 0, 3, 3, 6, 6]
c = [complex(a, b) for a, b in zip(data[:-1:2], data[1::2])]
print(c)