master
PAOV 4 years ago
parent 3dcbeb9284
commit 1ead061246
  1. 1
      .gitignore
  2. 7
      choose/admin.py
  3. 23
      choose/migrations/0007_choice.py
  4. 25
      choose/migrations/0008_choice_votes_alter_choice_users.py
  5. 25
      choose/migrations/0009_alter_choice_users_alter_choice_votes.py
  6. 7
      choose/models.py
  7. 92
      choose/templates/choose.html
  8. 18
      choose/templates/login.html
  9. 49
      choose/views.py
  10. 12
      requirements.txt
  11. 9
      sync.py
  12. 1
      tea/settings.py
  13. 3
      tea/urls.py

1
.gitignore vendored

@ -1,2 +1,3 @@
/venv/
/db.sqlite3
/media/

@ -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)

@ -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)),
],
),
]

@ -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),
),
]

@ -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),
),
]

@ -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')

@ -6,16 +6,34 @@
</head>
<body>
<table>
{% for category_name,category in categories.items %}
<tbody>
<tr>
<td colspan="2">
<th></th>
<th>Название</th>
<th>Цена за 50 гр</th>
<th>Вес</th>
<th></th>
</tr>
</tbody>
{% for category_name,category in categories.items %}
<tbody>
<tr class="category_tr">
<th colspan="5">
<h3>{{ category_name }}</h3>
</td>
</th>
</tr>
</tbody>
<tbody>
{% for type_name,type in category.items %}
<tr>
<td>
<label for="{{ type_name }}">{{ type_name }}[{{ type.price }}]:</label>
<img src="{{ type.pic }}" alt="{{ type_name }}" height="100px" width="100px">
</td>
<td>
<label for="{{ type_name }}">{{ type_name }}</label>
</td>
<td>{{ type.price }}</td>
<td>
<select name="{{ type_name }}" id="{{ type_name }}" onchange="change(value, '{{ type_name }}')">
{% for m in ms %}
@ -23,9 +41,12 @@
{% endfor %}
</select>
</td>
<td id="price {{ type_name }}">
0
</td>
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
<h3 id="sum_h">0</h3>
@ -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 @@
})
}
</script>
<style>
table {
border: none;
margin-bottom: 20px;
}
table th {
font-weight: bold;
text-align: left;
border: none;
padding: 10px 15px;
background: #d8d8d8;
font-size: 14px;
}
table tr th:first-child {
border-radius: 8px 0 0 8px;
}
table tr th:last-child {
border-radius: 0 8px 8px 0;
width: 35px;
}
table td {
text-align: left;
border: none;
padding: 10px 15px;
font-size: 14px;
vertical-align: top;
}
table tbody tr:nth-child(even) {
background: #f3f3f3;
}
table tr td:first-child {
border-radius: 8px 0 0 8px;
}
table tr td:last-child {
border-radius: 0 8px 8px 0;
}
table tr.category_tr th {
border-radius: 8px 8px 8px 8px;
background: #ececec;
}
table h3 {
margin-top: 0px;
margin-bottom: 0px;
}
</style>
</html>

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<div class="log-form">
<h2>Login to your account</h2>
<form method="POST">
{% csrf_token %}
<input id="username" name="username" type="username" title="username" placeholder="username" />
<input id="password" name="password" type="password" title="username" placeholder="password" />
<button type="submit" class="btn">Login</button>
</form>
</div>
</body>
</html>

@ -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):
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'})

@ -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

@ -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 TeaType.objects.filter(name=ttype).first() is None:
if 'shop' in href:
_, created = TeaType.objects.get_or_create(
TeaType.objects.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(
TeaType.objects.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)
for tea_type in list(TeaType.objects.all()):
if tea_type.one_item:
r = requests.get(

@ -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'
]

@ -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)

Loading…
Cancel
Save