From 1ead061246f0f845a5796953670608cd82a793bc Mon Sep 17 00:00:00 2001 From: PAOV Date: Thu, 13 Oct 2022 03:35:33 +0300 Subject: [PATCH] forth --- .gitignore | 1 + choose/admin.py | 7 +- choose/migrations/0007_choice.py | 23 ++++ .../0008_choice_votes_alter_choice_users.py | 25 ++++ ...9_alter_choice_users_alter_choice_votes.py | 25 ++++ choose/models.py | 7 ++ choose/templates/choose.html | 116 +++++++++++++++--- choose/templates/login.html | 18 +++ choose/views.py | 53 +++++++- requirements.txt | 12 ++ sync.py | 29 ++--- tea/settings.py | 1 + tea/urls.py | 3 +- 13 files changed, 279 insertions(+), 41 deletions(-) create mode 100644 choose/migrations/0007_choice.py create mode 100644 choose/migrations/0008_choice_votes_alter_choice_users.py create mode 100644 choose/migrations/0009_alter_choice_users_alter_choice_votes.py create mode 100644 choose/templates/login.html create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore index 46e17b3..aa93f3c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /venv/ /db.sqlite3 +/media/ \ No newline at end of file diff --git a/choose/admin.py b/choose/admin.py index 7252e33..1bba6f7 100644 --- a/choose/admin.py +++ b/choose/admin.py @@ -1,7 +1,7 @@ from django.contrib import admin # Register your models here. -from choose.models import Tea, TeaType, TeaCategory, Pic +from choose.models import Tea, TeaType, TeaCategory, Pic, Choice class TeaCategoryAdmin(admin.ModelAdmin): @@ -20,7 +20,12 @@ class PicAdmin(admin.ModelAdmin): list_display = ('href',) +class ChoiceAdmin(admin.ModelAdmin): + list_display = ('choice',) + + admin.site.register(Tea, TeaAdmin) admin.site.register(TeaType, TeaTypeAdmin) admin.site.register(TeaCategory, TeaCategoryAdmin) admin.site.register(Pic, PicAdmin) +admin.site.register(Choice, ChoiceAdmin) diff --git a/choose/migrations/0007_choice.py b/choose/migrations/0007_choice.py new file mode 100644 index 0000000..f1579a6 --- /dev/null +++ b/choose/migrations/0007_choice.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.2 on 2022-10-12 22:18 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('choose', '0006_teatype_preferred'), + ] + + operations = [ + migrations.CreateModel( + name='Choice', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('choice', models.CharField(max_length=3000)), + ('users', models.ManyToManyField(to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/choose/migrations/0008_choice_votes_alter_choice_users.py b/choose/migrations/0008_choice_votes_alter_choice_users.py new file mode 100644 index 0000000..bdeefd4 --- /dev/null +++ b/choose/migrations/0008_choice_votes_alter_choice_users.py @@ -0,0 +1,25 @@ +# Generated by Django 4.1.2 on 2022-10-13 00:31 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('choose', '0007_choice'), + ] + + operations = [ + migrations.AddField( + model_name='choice', + name='votes', + field=models.ManyToManyField(related_name='voted_by', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='choice', + name='users', + field=models.ManyToManyField(related_name='chosen_by', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/choose/migrations/0009_alter_choice_users_alter_choice_votes.py b/choose/migrations/0009_alter_choice_users_alter_choice_votes.py new file mode 100644 index 0000000..7bae486 --- /dev/null +++ b/choose/migrations/0009_alter_choice_users_alter_choice_votes.py @@ -0,0 +1,25 @@ +# Generated by Django 4.1.2 on 2022-10-13 00:32 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('choose', '0008_choice_votes_alter_choice_users'), + ] + + operations = [ + migrations.AlterField( + model_name='choice', + name='users', + field=models.ManyToManyField(related_name='choose', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='choice', + name='votes', + field=models.ManyToManyField(related_name='vote', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/choose/models.py b/choose/models.py index fee9351..c50dd60 100644 --- a/choose/models.py +++ b/choose/models.py @@ -1,3 +1,4 @@ +from django.conf import settings from django.db import models @@ -49,3 +50,9 @@ class Tea(models.Model): def __str__(self): return self.name + + +class Choice(models.Model): + choice = models.CharField(max_length=3000) + users = models.ManyToManyField(settings.AUTH_USER_MODEL, 'choose') + votes = models.ManyToManyField(settings.AUTH_USER_MODEL, 'vote') diff --git a/choose/templates/choose.html b/choose/templates/choose.html index 3439749..a5a62f7 100644 --- a/choose/templates/choose.html +++ b/choose/templates/choose.html @@ -6,26 +6,47 @@ + + + + + + + + + {% for category_name,category in categories.items %} - - + + - - - - {% endfor %} + + + + + {% for type_name,type in category.items %} + + + + + + + + {% endfor %} + {% endfor %}
НазваниеЦена за 50 грВес
+

{{ category_name }}

- - {% for type_name,type in category.items %} -
- - - -
+ {{ type_name }} + + + {{ type.price }} + + + 0 +

0

@@ -64,6 +85,8 @@ function change(value, type) { choice[type] = parseInt(value) + const price_el = document.getElementById('price ' + type); + price_el.innerText = parseInt(value) / 50 * parseInt(a[type].price) sum_price() } @@ -87,13 +110,16 @@ } function confirm_choice() { + let mychoice = {} + for (let key in choice) + mychoice[a[key].preferred] = choice[key] const request = new Request( 'confirm-choice', { method: 'POST', headers: {'X-CSRFToken': csrftoken}, mode: 'same-origin', - body: JSON.stringify(choice) + body: JSON.stringify(mychoice) } ); fetch(request).then((response) => response.json()) @@ -102,4 +128,58 @@ }) } + \ No newline at end of file diff --git a/choose/templates/login.html b/choose/templates/login.html new file mode 100644 index 0000000..7504be6 --- /dev/null +++ b/choose/templates/login.html @@ -0,0 +1,18 @@ + + + + + Login + + +
+

Login to your account

+
+ {% csrf_token %} + + + +
+
+ + \ No newline at end of file diff --git a/choose/views.py b/choose/views.py index f73e86a..a6683ca 100644 --- a/choose/views.py +++ b/choose/views.py @@ -1,15 +1,37 @@ import json from collections import OrderedDict +from django.contrib.auth import authenticate, login from django.http import JsonResponse, HttpResponse -from django.shortcuts import render +from django.shortcuts import render, redirect from django.template import loader -from .models import Tea, TeaType, TeaCategory, Pic +from .models import Tea, TeaType, TeaCategory, Pic, Choice # Create your views here. from .utils import get_extension +def login_view(request): + if request.method == 'POST': + username = request.POST['username'] + password = request.POST['password'] + user = authenticate(username=username, password=password) + if user is not None and user.is_active and user.is_authenticated: + login(request, user) + return redirect(home) + return render(request, 'login.html') + + +def login_requiered(func): + def wrapper(*args, **kwargs): + request = args[0] + if request.user.is_authenticated: + return func(*args, **kwargs) + else: + return redirect('login_view') + return wrapper + + def list_of_teas(): dic = OrderedDict() for cat in TeaCategory.objects.all(): @@ -20,12 +42,13 @@ def list_of_teas(): dic[tt.category.name][tt.name] = OrderedDict() dic[tt.category.name][tt.name]['preferred'] = tt.preferred.name dic[tt.category.name][tt.name]['price'] = int(tt.preferred.price / 100) - dic[tt.category.name][tt.name]['pic'] = str(tt.preferred.pic.id) + '.' + get_extension( + dic[tt.category.name][tt.name]['pic'] = '/media/' + str(tt.preferred.pic.id) + '.' + get_extension( tt.preferred.pic.href) return {'categories': dic, 'ms': [0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500]} +@login_requiered def home(request): context = list_of_teas() template = loader.get_template('choose.html') @@ -33,5 +56,25 @@ def home(request): def confirm_choose(request): - choice = json.loads(request.body.decode(encoding='UTF-8')) - return JsonResponse({'response': 'ok'}) + if request.user.is_authenticated: + choice = json.loads(request.body.decode(encoding='UTF-8')) + d ={} + for key in choice: + tea = Tea.objects.get(name=key) + d[tea.id] = choice[key] + choice_string = json.dumps(d, sort_keys=True) + previous = Choice.objects.filter(users__in=[request.user]).first() + if previous is not None: + if previous.choice == choice_string: + return JsonResponse({'response': 'unchanged'}) + previous.users.remove(request.user) + if not previous.users.exists(): + previous.delete() + my_choice, _ = Choice.objects.get_or_create(choice=choice_string) + if request.user not in list(my_choice.users.all()): + my_choice.users.add(request.user) + if request.user in list(my_choice.votes.all()): + my_choice.votes.remove(request.user) + return JsonResponse({'response': 'ok'}) + else: + return JsonResponse({'response': 'unauthenticated'}) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..9fb8eb8 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,12 @@ +asgiref==3.5.2 +beautifulsoup4==4.11.1 +certifi==2022.9.24 +charset-normalizer==2.1.1 +Django==4.1.2 +django-cors-headers==3.13.0 +idna==3.4 +requests==2.28.1 +soupsieve==2.3.2.post1 +sqlparse==0.4.3 +tzdata==2022.4 +urllib3==1.26.12 diff --git a/sync.py b/sync.py index d7135ee..d068ff5 100644 --- a/sync.py +++ b/sync.py @@ -45,22 +45,19 @@ for item in ul.contents: ttype = i.contents[0].contents[0] href = i.contents[0].attrs['href'] if i.contents[0].attrs['href'].startswith( 'https') else 'https://chainiisvet.ru' + i.contents[0].attrs['href'] - if 'shop' in href: - _, created = TeaType.objects.get_or_create( - shop_name=href[href[:href.rfind('/', 0, len(href) - 1)].rfind('/') + 1:-1], - name=ttype, - category=category, - one_item=True) - else: - _, created = TeaType.objects.get_or_create( - shop_name=href[href.rfind('/', 0, len(href) - 1) + 1:-1], - name=ttype, - category=category, - one_item=False) - print(created) - print(category, end=':') - print(ttype, end=':') - print(href) + if TeaType.objects.filter(name=ttype).first() is None: + if 'shop' in href: + TeaType.objects.create( + shop_name=href[href[:href.rfind('/', 0, len(href) - 1)].rfind('/') + 1:-1], + name=ttype, + category=category, + one_item=True) + else: + TeaType.objects.create( + shop_name=href[href.rfind('/', 0, len(href) - 1) + 1:-1], + name=ttype, + category=category, + one_item=False) for tea_type in list(TeaType.objects.all()): if tea_type.one_item: r = requests.get( diff --git a/tea/settings.py b/tea/settings.py index d656f4d..b8ff5c2 100644 --- a/tea/settings.py +++ b/tea/settings.py @@ -26,6 +26,7 @@ SECRET_KEY = 'django-insecure-u=yu7(3@719dv(dtgy3wz_%yaw((r9-sh4exp(qf@to8o-e=e@ DEBUG = True ALLOWED_HOSTS = [ + '127.0.0.1', '10.15.0.1' ] diff --git a/tea/urls.py b/tea/urls.py index 2a33f32..d1b1aba 100644 --- a/tea/urls.py +++ b/tea/urls.py @@ -23,7 +23,8 @@ import choose.views urlpatterns = [ path('admin/', admin.site.urls), path('', choose.views.home), - path('confirm-choice', choose.views.confirm_choose) + path('confirm-choice', choose.views.confirm_choose), + path('login', choose.views.login_view, name='login_view') ] if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)