С Новым годом! Форум программистов, компьютерный форум, киберфорум
Python: Django
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/8: Рейтинг темы: голосов - 8, средняя оценка - 4.88
0 / 0 / 0
Регистрация: 02.02.2024
Сообщений: 11

Добавление товара в корзину вместе с размером через checkbox

05.02.2024, 23:34. Показов 1917. Ответов 2

Студворк — интернет-сервис помощи студентам
Всем доброго времени суток.

Прошу сразу не кидаться какахами, я только учусь. Начал изучать джанго и вроде все шло гладко, пока не столкнулся с проблемой добавления товара в корзину вместе с размером. Сам товар добавить нет проблем, но мне нужно, что бы пользователь выбирал размер через чекбокс и после нажатия на кнопку "добавить в корзину" в нее попадал не просто товар, а именно с нужным выбранным размером.

Вот модели товара, размеров и корзины

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Product(models.Model):
    article = models.CharField(max_length=12,null=False,blank=False,unique=True,primary_key=True)
    img = models.ImageField(upload_to='products_images')
    price = models.DecimalField(max_digits=9,decimal_places=2)
    description = models.TextField(null=True,blank=True)
    gender = models.CharField(max_length=12,null=False,blank=False)
    is_child = models.BooleanField(null=False)
    season = models.CharField(max_length=12,null=False)
    color = models.CharField(max_length=24,null=False)
    sizes = models.ForeignKey(to='Size',on_delete=models.CASCADE,to_field='article')
 
    def __str__(self):
        return f"{self.article}"
 
 
class Size(models.Model):
    article = models.CharField(max_length=12,null=False,unique=True)
    article_size = models.ForeignKey(to='ArticleSize',on_delete=models.CASCADE,to_field='article_size')
 
    def __str__(self):
        return f"{self.article}"
 
class ArticleSize(models.Model):
    article_size = models.CharField(max_length=12, null=False, unique=True)
    size_name = models.CharField(max_length=12,null=False,blank=False)
    qty = models.SmallIntegerField()
    to_article = models.CharField(max_length=12, null=False)
 
    def __str__(self):
        return f"{self.article_size}"
 
class Basket(models.Model):
    user = models.ForeignKey(to=User, on_delete=models.CASCADE)
    product = models.ForeignKey(to=Product, on_delete=models.CASCADE,to_field='article')
    size = models.ForeignKey(to=ArticleSize,on_delete=models.CASCADE,to_field='article_size')
    qty = models.PositiveSmallIntegerField(default=0)
    create_time_stamp = models.DateTimeField(auto_now_add=True)
    def __str__(self):
        return f"Корзина для {self.user.email} товар {self.product.article},размер {self.size.size_name}"
Вот модель формы:

Python
1
2
3
4
5
6
7
class CheckboxForm(forms.Form):
    checkbox_size = forms.CharField(widget=forms.CheckboxInput(attrs={
    'class':'size_checkbox', 'type':'checkbox', 'name':'size_checkbox'}),required=True)
 
    class Meta:
        model = ArticleSize
        fields = ('checkbox_size')
Вот вьюха:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def products(request):
    form = CheckboxForm()
 
    context = {
        'title': "Магазин",
        'footer_1': "127015, Москва, Бумажный пр-д., д. 14, стр. 2 ООО «НИКАМЕД».",
        'footer_2': "Копирование материалов запрещено.",
        'products': Product.objects.all(),
        'sizes': Size.objects.all(),
        'article_size': ArticleSize.objects.all(),
        'form': form,
 
    }
    return render(request, 'products/products.html', context)
 
def basket_add(request,product,size):
    product = Product.objects.get(article=product)
    size = ArticleSize.objects.get(article_size=size)
    basket = Basket.objects.filter(user=request.user,product=product,size=size)
 
    if not basket.exists():
        Basket.objects.create(user=request.user,product=product,qty=1,size=size)
    else:
        basket = basket.last()
        basket.qty += 1
        basket.save()
    return HttpResponseRedirect(request.META['HTTP_REFERER'])
Вот HTML:

HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 <div class="goods-group">
                   {% for product in products %}
                       <div class="goods">
                               <div class="shoe-photo">
                                   <a href="{% url 'products:item_info' %}">
                                        <img src="{{ product.img.url }}" alt="нет фото">
                                   </a>
                                   <a href="#">
                                        <svg class="photo-heart" fill="#C0BFBF" width="64px" height="64px" viewBox="0 0 200 200" data-name="Layer 1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><title></title><path d="M171.28,41.69a48.29,48.29,0,0,0-68.5,0l-2.5,3-2.5-2.5a48.29,48.29,0,0,0-68.5,0c-19,18.5-19,49-1,68l50,53a29.92,29.92,0,0,0,43.5,0l50.5-53.5c17.5-19.5,17-49.5-1-68Zm-14,53.5-50.5,53.5a10.26,10.26,0,0,1-14.5,0l-50-53c-10.5-11.5-10.5-29,.5-40s29-11,40.5,0l2.5,2.5c8,8,20.5,8,28,0l2.5-2.5a28.37,28.37,0,0,1,40,0,27.78,27.78,0,0,1,1,39.5Z"></path></g></svg>
                                   </a>
                                </div>
 
                           <a href="#">
                                <div class="price">{{product.price}} руб</div>
                           </a>
                           <a href="#">
                                <div class="description">{{product.description}}</div>
 
                           </a>
 
                           <div class="sizes-group">
                                   <form action="" method="post">
                                       {% for item in sizes %}
                                           {% if item.article == product.article %}
                                                {% for size in article_size %}
                                                    {% if size.to_article == item.article %}
                                                           <label>
                                                               {{form.checkbox_size}}
                                                               <span class="title_checkbox">{{size.size_name}}</span>
                                                           </label>
                                                    {% else %}
                                                    {% endif %}
                                                {% endfor %}
                                           {% else %}
                                           {% endif %}
                                       {% endfor %}
                                   </form>
                           </div>
 
                           <a href="{% url 'products:basket_add' product=product.article size=product.sizes.article_size %}">
                               <button class="btn" type="submit">
                                   <svg class="button-cart" fill="#C0BFBF" width="64px" height="64px" viewBox="-2 -2 204.00 204.00" data-name="Layer 1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><title></title><path d="M183.25,52.75a18.22,18.22,0,0,0-7-1h-91c-3.5,0-8-.5-11.5.5a9.64,9.64,0,0,0-7.5,9.5,10,10,0,0,0,10,10h90.5l-8,42a10.22,10.22,0,0,1-10,8h-75a10.66,10.66,0,0,1-10-8l-16-74a20.3,20.3,0,0,0-19.5-16h-7a10,10,0,0,0,0,20h7l16,74c3,14,15,23.5,29.5,23.5h75c12,0,24.5-8,28-19.5,2.5-8,4-17,5.5-25,1.5-8.5,3.5-17,5-25a17.76,17.76,0,0,0,1-5,17,17,0,0,0,.5-5c0-4-2-8-5.5-9Zm-132,108.5a15,15,0,0,0,30,0h0a15,15,0,0,0-30,0Zm90,0a15,15,0,1,0,15-15,15,15,0,0,0-15,15v0Z"></path></g></svg>
                                   В корзину</button>
                           </a>
                       </div>
                   {% endfor %}
               </div>
           </div>
Подскажите, как такие задачи решаются? Может я вообще не в том направлении двигаюсь и надо все переписать?

Извините за сумбур, готов уточнить все что необходимо.

Заранее всем спасибо!
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.02.2024, 23:34
Ответы с готовыми решениями:

Реализовать добавление товара в корзину через сессию
Всем привет. Недавно начал заниматься веб-разработкой, мой первый проект с фреймворком laravel. По заданию необходимо реализовать...

Добавление товара в корзину.
Добавление товара в корзину. День добрый. Вопрос жизни и смерти. У меня есть каталог с занесенными элементами. Есть страница на в...

Добавление товара в корзину
Всем доброго времени суток. У меня такой вопрос почему по нажатию кнопки не добавляется товар в таблицу при нажатии на кнопку? Дело вот в...

2
0 / 0 / 0
Регистрация: 02.02.2024
Сообщений: 11
08.02.2024, 01:48  [ТС]
Немного подправил код, теперь все заработало, ну как, почти заработало. Если захардкодить во вьюхе данные об объекте size из шаблона, то все ок, но если я пытаюсь просто получить значение из request.POST.get('size'), то мне всегда приходить None.

Вот исправленные модели, шаблон и вьюха.

Модели:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Product(models.Model):
    article = models.CharField(max_length=12,null=False,blank=False,unique=True,primary_key=True)
    img = models.ImageField(upload_to='products_images')
    price = models.DecimalField(max_digits=9,decimal_places=2)
    description = models.TextField(null=True,blank=True)
    gender = models.CharField(max_length=12,null=False,blank=False)
    is_child = models.BooleanField(null=False)
    season = models.CharField(max_length=12,null=False)
    color = models.CharField(max_length=24,null=False)
    sizes = models.ForeignKey(to='Size',on_delete=models.CASCADE,to_field='article_size')
 
    def __str__(self):
        return f"{self.article}"
 
 
class Size(models.Model):
    article_size = models.CharField(max_length=12,null=False,unique=True,primary_key=True)
    size_name = models.CharField(max_length=12, null=False, blank=False)
    qty = models.SmallIntegerField()
    to_article = models.CharField(max_length=12, null=False)
 
    def __str__(self):
        return f"{self.article_size}"
 
 
 
class Basket(models.Model):
    user = models.ForeignKey(to=User, on_delete=models.CASCADE)
    product = models.ForeignKey(to=Product, on_delete=models.CASCADE,to_field='article')
    size = models.ForeignKey(to=Size,on_delete=models.CASCADE,to_field='article_size')
    qty = models.PositiveSmallIntegerField(default=0)
    create_time_stamp = models.DateTimeField(auto_now_add=True)
    def __str__(self):
        return f"Корзина для {self.user.email} товар {self.product.article},размер {self.size.size_name}"
Шаблон:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 <div class="goods-group">
        {% for product in products %}
            <div class="goods">
                <div class="shoe-photo">
                    <a href="{% url 'products:item_info' %}">
                        <img src="{{ product.img.url }}" alt="нет фото">
                    </a>
                    <a href="#">
                        <svg class="photo-heart" fill="#C0BFBF" width="64px" height="64px" viewBox="0 0 200 200"
                             data-name="Layer 1" id="Layer_1" xmlns="http://www.w3.org/2000/svg">
                            <g id="SVGRepo_bgCarrier" stroke-width="0"></g>
                            <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
                            <g id="SVGRepo_iconCarrier"><title></title>
                                <path d="M171.28,41.69a48.29,48.29,0,0,0-68.5,0l-2.5,3-2.5-2.5a48.29,48.29,0,0,0-68.5,0c-19,18.5-19,49-1,68l50,53a29.92,29.92,0,0,0,43.5,0l50.5-53.5c17.5-19.5,17-49.5-1-68Zm-14,53.5-50.5,53.5a10.26,10.26,0,0,1-14.5,0l-50-53c-10.5-11.5-10.5-29,.5-40s29-11,40.5,0l2.5,2.5c8,8,20.5,8,28,0l2.5-2.5a28.37,28.37,0,0,1,40,0,27.78,27.78,0,0,1,1,39.5Z"></path>
                            </g>
                        </svg>
                    </a>
                </div>
 
                <a href="#">
                    <div class="price">{{product.price}} руб</div>
                </a>
                <a href="#">
                    <div class="description">{{product.description}}</div>
 
                </a>
 
                <div class="sizes-group">
                    <form id="size_checkbox_form" action="/" method="post">
                        {% csrf_token %}
                        {% for size in sizes %}
                            {% if product.article == size.to_article %}
                                <label>
                                    <input class="size_checkbox" type="checkbox" name="{{size}}" value="{{size}}">
                                    <span class="title_checkbox">{{size.size_name}}</span>
                                </label>
                            {%endif%}
                        {% endfor %}
                    </form>
                </div>
                    <button   form="size_checkbox_form" formaction="{% url 'products:basket_add' product.article %}" class="btn" type="submit" >
                        <svg class="button-cart" fill="#C0BFBF" width="64px" height="64px" viewBox="-2 -2 204.00 204.00"
                             data-name="Layer 1" id="Layer_1" xmlns="http://www.w3.org/2000/svg">
                            <g id="SVGRepo_bgCarrier" stroke-width="0"></g>
                            <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
                            <g id="SVGRepo_iconCarrier"><title></title>
                                <path d="M183.25,52.75a18.22,18.22,0,0,0-7-1h-91c-3.5,0-8-.5-11.5.5a9.64,9.64,0,0,0-7.5,9.5,10,10,0,0,0,10,10h90.5l-8,42a10.22,10.22,0,0,1-10,8h-75a10.66,10.66,0,0,1-10-8l-16-74a20.3,20.3,0,0,0-19.5-16h-7a10,10,0,0,0,0,20h7l16,74c3,14,15,23.5,29.5,23.5h75c12,0,24.5-8,28-19.5,2.5-8,4-17,5.5-25,1.5-8.5,3.5-17,5-25a17.76,17.76,0,0,0,1-5,17,17,0,0,0,.5-5c0-4-2-8-5.5-9Zm-132,108.5a15,15,0,0,0,30,0h0a15,15,0,0,0-30,0Zm90,0a15,15,0,1,0,15-15,15,15,0,0,0-15,15v0Z"></path>
                            </g>
                        </svg>
                        В корзину
                    </button>
            </div>
        {% endfor %}
    </div>
Вьюха:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
def products(request):
    form = CheckboxForm()
 
    context = {
        'title': "Магазин",
        'footer_1': "127015, Москва, Бумажный пр-д., д. 14, стр. 2 ООО «НИКАМЕД».",
        'footer_2': "Копирование материалов запрещено.",
        'products': Product.objects.all(),
        'sizes': Size.objects.all(),
        'form': form,
 
    }
    return render(request, 'products/products.html', context)
 
def basket_add(request,product_id):
    if request.method == 'POST':
        product = Product.objects.get(article=product_id)
        size = request.POST.get('size')
 
 
        print(size)
        basket = Basket.objects.filter(user=request.user,product=product,size=size)
 
        if not basket.exists():
            Basket.objects.create(user=request.user,product=product,qty=1,size=size)
        else:
            basket = basket.last()
            basket.qty += 1
            basket.save()
        return HttpResponseRedirect(request.META['HTTP_REFERER'])
    else:
        print("NOT POST")
Может кто-то знает, почему прилетает None при submite на кнопку? Может какой атрибут забыл указать?

Спасибо.

Добавлено через 4 часа
Я решил как это сделать, если кому-то интересно, пишите, выложу код.
0
57 / 15 / 6
Регистрация: 08.08.2020
Сообщений: 266
10.02.2024, 21:39
Не очень понятна мне логика кода. Размер приходит во вьюху их форму предусмотренной именно для размера? Без товара?

Добавлено через 5 минут
По всей видимости не срабатывает условие if в 32 строке

Добавлено через 5 минут
А че это за product.article? , почему экшин в форме на главную страницу?

Добавлено через 11 минут
Как то каряво мне кажется) не надо разделять продукт и размер на две формы. Все надо в одной форме. CheckboxForm(forms.Form) - это форма не связанная с моделью, надо сделать ее связанной с моделью товара, и прописать в ней все поля товара(продукта), включая и поле size. В этом поле size прописывается класс кажется forms.ModelChoiceField, и в HTML пропиши лучше select а не checkpoint, все размеры выйдут списком автоматически.

Добавлено через 6 минут
И вьюху надо как бы по канонам прописать, разделить ее на две части через if , первая если приходит метод пост, в нем метод is_valide() проверяет валидность данных из формы, вторая для отрисовки первоначальной страницы и если ошибка в валидации.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.02.2024, 21:39
Помогаю со студенческими работами здесь

Добавление товара в корзину
Проблема с выводом массива из сессии.В данном коде выводится только один продукт, как реализовать вывод всех данных из сессии. &lt;?php ...

Добавление товара в корзину
Привет Всем :) Как реализовать вот такую задачу(Не через CMS): Имеется список с товарами. Рядом кнопка &quot;Добавить&quot;. При...

Добавление товара в корзину
Здравствуйте! Имеется 2 файла index.jsp и cart.jsp. На index.jsp хранятся товары, в cart.jsp должна быть в дальнейшем сделана корзина....

Добавление товара в корзину
Ув. форумчане, помогите разобраться или подскажите где копать. Есть товар который продается по весу(кг) соответственно при добавлении...

Добавление товара в корзину
Здравствуйте. Есть два темплэйта: первый страница для заказа товара(товар подгружается с PostGRE), около товара есть кнопка добавить в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru