def __init__(self, *args, **kwargs): self.request = kwargs.pop('request', None) parent = kwargs.get('instance') if 'initial' not in kwargs: kwargs['initial'] = [] if isinstance(parent, Product) and parent.pk is not None: keys_remove = [] product_attributes = ProductAttribute.objects.filter( product_id=parent) data = ast.literal_eval(to_python(parent.config)) # remove all combine in config exist in database for product_attribute in product_attributes: attributes = ProductAttributeCombination.objects.filter( pro_attribute_id=product_attribute) str_value = "" array_values = [] for attribute in attributes: str_value += "{}:{}, ".format(attribute.attribute_id.pk, attribute.attribute_id.name) array_values.append(attribute.attribute_id.pk) if len(str_value) > 0 or len(array_values) > 0: # find key in config[] and remove it if isinstance(data, dict) and len(list(data.keys())) > 0: try: # tmp_key = str(0) # find max in list key for key in list(data.keys()): if isSubArray(list(data[key]), array_values): keys_remove.append(key) except (ValueError, TypeError, IndexError): pass if len(kwargs['initial']) <= 0 and isinstance(parent.config, str): try: data = ast.literal_eval(to_python(parent.config)) if isinstance(data, dict) and len(list(data.keys())) > 0: for key in list(data.keys()): if key in keys_remove: continue str_value = "" for item in data.get(key): attribute = Attribute.objects.get(pk=int(item)) str_value += "{}:{}, ".format( item, attribute.name) # kwargs['initial'].insert(0,{'combination': (key, str_value)}) kwargs['initial'].append( {'combination': (key, str_value)}) except (ValueError, TypeError, IndexError): pass else: kwargs['initial'] = [] kwargs['initial'].append( {'combination': ('', '--Choice One Item--')}) super(ProductAttributeInlineFormSet, self).__init__(*args, **kwargs)
def __iter__(self): """ Iterate over the items in the cart and get the items from the database. """ item_ids = self.cart.keys() # get the item objects and add them to the cart items = CartItem.objects.filter(find_item_id__in=item_ids, cart_id=self.cart_obj) cart = self.cart.copy() for item in items: self.cart[str(item.find_item_id)]['item'] = item for item in self.cart.values(): try: _item = next(serializers.deserialize( "json", item['obj'])).object if to_python( item['obj']) else None if isinstance(_item, ProductAttribute): item['price'] = str(_item.price) item['total_price'] = str( Decimal(item['price']) * item['quantity']) yield item except IndexError: break
def clean(self): result = super(ProductAttributeInlineFormSet, self).clean() instance = getattr(self, 'instance', None) for form in self.forms: if not hasattr(form, 'cleaned_data'): continue data = form.cleaned_data valid = False if 'DELETE' in data and data['DELETE']: valid = True else: if instance.config is not None and isinstance( instance.config, str) and is_json(instance.config): config = ast.literal_eval(to_python(instance.config)) try: if 'combination' in data and int( data['combination'] ) >= 0 and data['combination'] in config: valid = True except ValueError: valid = True if data['attr_name'] in [ None, '' ] and instance is not None and isinstance(instance.name, str): data['attr_name'] = "{} {}".format(instance.name, generate_slug(8)) if not valid: raise forms.ValidationError( "A Combination is a string has len() >=0.") return result
def is_valid(self): instance = getattr(self, 'instance', None) result = super().is_valid() if self.is_bound: for form in self.forms: data = form.cleaned_data valid = False if 'DELETE' in data and data['DELETE']: valid = True elif data['attr_name'] is None: valid = False else: if instance.config is not None and isinstance( instance.config, str) and is_json(instance.config): config = ast.literal_eval(to_python(instance.config)) try: if 'combination' in data and int( data['combination'] ) >= 0 and data['combination'] in config: valid = True except ValueError: valid = True if not valid: result = result and valid if hasattr(form, 'nested'): result = result and form.nested.is_valid() return result
def save(self): # update the session cart self.session[settings.CART_SESSION_ID] = self.cart if self.request.user.is_authenticated: # load items from session and add to database for key, value in self.cart.items(): try: obj_item = CartItem.objects.get(cart_id=self.cart_obj, find_item_id=key) except CartItem.DoesNotExist: obj_item = CartItem.objects.create(cart_id=self.cart_obj, find_item_id=key) try: _item = next(serializers.deserialize( "json", value['obj'])).object if 'obj' in value else None if _item is not None and isinstance( _item, ProductAttribute): obj_item.find_item_id = key obj_item.class_of_item = value['obj'] obj_item.name = value['name'] obj_item.price = _item.price obj_item.original_price = obj_item.price obj_item.quantity = value['quantity'] obj_item.total_price = Decimal( obj_item.price) * value['quantity'] obj_item.save() except IndexError: break # load items from database and add to session items = CartItem.objects.filter(cart_id=self.cart_obj) for item in items: try: _item = next( serializers.deserialize( "json", item.class_of_item)).object if to_python( item.class_of_item) else None if _item is not None and isinstance( _item, ProductAttribute): self.cart[item.find_item_id] = { 'userid': self.request.user.id, 'item_id': _item.pk, 'obj': item.class_of_item, 'name': item.name, 'quantity': int(item.quantity), 'price': str(_item.price), 'image': preview(_item, 'mid') } except IndexError: break # mark the session as "modified" to make sure it is saved self.session.modified = True
def get_max_num(self, request, obj=None, **kwargs): max_num = get_max_combined(obj) if obj.product_id is not None and isinstance(obj.product_id, int): product = Product.objects.get(pk=obj.product_id) if isinstance(product, Product) and isinstance(obj.config, str): try: data = ast.literal_eval(to_python(product.config)) if isinstance(data, dict) and len(list(data.keys())) > 0: max_num = len(list(data.keys())) else: items = get_list_combined(product) product.config = json.dumps(items, cls=DjangoJSONEncoder) product.save() except (ValueError, TypeError, IndexError): items = {} product.config = json.dumps(items, cls=DjangoJSONEncoder) product.save() if not isinstance(max_num, int): max_num = super(ProductAttributeInline, self).get_max_num(request, obj, **kwargs) return max_num
def get_formset(self, request, obj=None, **kwargs): formset = super(ProductAttributeInline, self).get_formset(request, obj, **kwargs) formset.request = request def formfield_callback(field, **kwargs): formfield = field.formfield(**kwargs) if field.name == 'pro_attribute_id': formfield.queryset = ProductAttribute.objects.filter( product_id=self._parent_instance) return formfield if self._parent_instance is not None: kwargs['formfield_callback'] = formfield_callback choices = (('', '--Choice One Item--'), ) if isinstance(obj, Product) and isinstance(obj.config, str): try: data = ast.literal_eval(to_python(obj.config)) if isinstance(data, dict) and len(list(data.keys())) > 0: items = get_list_attributes(obj) for key in data: str_value = "" values = data.get(key) if check_exist_in_dict(values, items): continue for item in values: attribute = Attribute.objects.get(pk=int(item)) str_value += "{}:{}, ".format(item, attribute.name) option = (key, str_value) choices += (option, ) except (ValueError, TypeError, IndexError): choices = (('', '--Choice One Item--'), ) ProductAttributeInline.form = type( 'ProductAttributeInlineForm', (ProductAttributeInlineForm, ), { 'combination': forms.ChoiceField( label="Combination", choices=choices, required=True) }) return formset
def save(self, commit=True): result = super().save(commit=commit) instance = getattr(self, 'instance', None) for form in self.forms: data = form.cleaned_data if instance.config is not None and isinstance( instance.config, str) and is_json(instance.config): config = ast.literal_eval(to_python(instance.config)) id_pro_att = data[ 'pro_attribute_id'] if 'pro_attribute_id' in data else False com_val = data[ 'combination'] if 'combination' in data else False file_in_memory = data['file'] if 'file' in data else False if id_pro_att and com_val and file_in_memory: save_photo_formset(data, id_pro_att) if com_val in config: if not id_pro_att or not isinstance( id_pro_att, ProductAttribute): id_pro_att = form.save(commit=False) id_pro_att.save() if not isinstance(id_pro_att, ProductAttribute): continue try: if isinstance(id_pro_att, ProductAttribute) and com_val in config: id_pro_att.attributes.through.objects.filter( pro_attribute_id=id_pro_att.pk).delete() for item in config.get(str(com_val)): attribute = Attribute.objects.get(pk=int(item)) id_pro_att.attributes.add(attribute) id_pro_att.save() except (ValueError, TypeError, IndexError): continue if hasattr(form, 'nested'): if not self._should_delete_form(form): form.nested.save(commit=commit) return result