diff --git a/order/admin.py b/order/admin.py index de3fb3c..791e6d2 100644 --- a/order/admin.py +++ b/order/admin.py @@ -10,4 +10,5 @@ class CityAdmin(admin.ModelAdmin): @admin.register(Order) class OrderAdmin(admin.ModelAdmin): - pass + list_display = ['owner', 'phone', 'name', 'create_time', 'moderated', 'published'] + readonly_fields = ['create_time'] diff --git a/order/forms.py b/order/forms.py index db99637..e9c0261 100644 --- a/order/forms.py +++ b/order/forms.py @@ -31,3 +31,7 @@ class UnregisteredUserOrderCreationForm(BaseOrderCreationForm): RegexValidator(regex="^\\+7[0-9]{10}$"), ]) email = forms.EmailField(required=True) + + class Meta: + model = Order + fields = BaseOrderCreationForm.Meta.fields + ['phone', 'email'] diff --git a/order/migrations/0009_order_date_end_order_date_start.py b/order/migrations/0009_order_date_end_order_date_start.py new file mode 100644 index 0000000..23a6d2c --- /dev/null +++ b/order/migrations/0009_order_date_end_order_date_start.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.1 on 2022-09-27 22:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('order', '0008_alter_order_approximate_price_alter_order_square_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='order', + name='date_end', + field=models.DateField(blank=True, default=None), + ), + migrations.AddField( + model_name='order', + name='date_start', + field=models.DateField(blank=True, default=None), + ), + ] diff --git a/order/migrations/0010_alter_order_date_end_alter_order_date_start.py b/order/migrations/0010_alter_order_date_end_alter_order_date_start.py new file mode 100644 index 0000000..5ca8d7a --- /dev/null +++ b/order/migrations/0010_alter_order_date_end_alter_order_date_start.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.1 on 2022-09-27 22:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('order', '0009_order_date_end_order_date_start'), + ] + + operations = [ + migrations.AlterField( + model_name='order', + name='date_end', + field=models.DateField(blank=True, default=None, verbose_name='Дата окончания'), + ), + migrations.AlterField( + model_name='order', + name='date_start', + field=models.DateField(blank=True, default=None, verbose_name='Дата начала'), + ), + ] diff --git a/order/migrations/0011_order_email_order_phone.py b/order/migrations/0011_order_email_order_phone.py new file mode 100644 index 0000000..47cdd65 --- /dev/null +++ b/order/migrations/0011_order_email_order_phone.py @@ -0,0 +1,25 @@ +# Generated by Django 4.1.1 on 2022-09-28 08:04 + +import django.core.validators +from django.db import migrations, models +import order.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('order', '0010_alter_order_date_end_alter_order_date_start'), + ] + + operations = [ + migrations.AddField( + model_name='order', + name='email', + field=models.EmailField(max_length=254, null=True, validators=[order.models._email_validate], verbose_name='Email'), + ), + migrations.AddField( + model_name='order', + name='phone', + field=models.CharField(max_length=16, null=True, validators=[django.core.validators.RegexValidator(regex='^\\+7[0-9]{10}$'), order.models._phone_validate], verbose_name='Телефон'), + ), + ] diff --git a/order/migrations/0012_alter_order_date_end_alter_order_date_start.py b/order/migrations/0012_alter_order_date_end_alter_order_date_start.py new file mode 100644 index 0000000..3b5a582 --- /dev/null +++ b/order/migrations/0012_alter_order_date_end_alter_order_date_start.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.1 on 2022-09-28 08:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('order', '0011_order_email_order_phone'), + ] + + operations = [ + migrations.AlterField( + model_name='order', + name='date_end', + field=models.DateField(default=None, null=True, verbose_name='Дата окончания'), + ), + migrations.AlterField( + model_name='order', + name='date_start', + field=models.DateField(default=None, null=True, verbose_name='Дата начала'), + ), + ] diff --git a/order/migrations/0013_alter_order_date_end_alter_order_date_start.py b/order/migrations/0013_alter_order_date_end_alter_order_date_start.py new file mode 100644 index 0000000..12b872c --- /dev/null +++ b/order/migrations/0013_alter_order_date_end_alter_order_date_start.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.1 on 2022-09-28 08:42 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('order', '0012_alter_order_date_end_alter_order_date_start'), + ] + + operations = [ + migrations.AlterField( + model_name='order', + name='date_end', + field=models.DateField(blank=True, default=None, null=True, verbose_name='Дата окончания'), + ), + migrations.AlterField( + model_name='order', + name='date_start', + field=models.DateField(blank=True, default=None, null=True, verbose_name='Дата начала'), + ), + ] diff --git a/order/migrations/0014_order_create_time.py b/order/migrations/0014_order_create_time.py new file mode 100644 index 0000000..9188ff7 --- /dev/null +++ b/order/migrations/0014_order_create_time.py @@ -0,0 +1,19 @@ +# Generated by Django 4.1.1 on 2022-09-28 08:47 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('order', '0013_alter_order_date_end_alter_order_date_start'), + ] + + operations = [ + migrations.AddField( + model_name='order', + name='create_time', + field=models.DateTimeField(default=datetime.datetime.now, editable=False), + ), + ] diff --git a/order/migrations/0015_order_moderated_order_published_and_more.py b/order/migrations/0015_order_moderated_order_published_and_more.py new file mode 100644 index 0000000..14478d9 --- /dev/null +++ b/order/migrations/0015_order_moderated_order_published_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 4.1.1 on 2022-09-28 08:51 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('order', '0014_order_create_time'), + ] + + operations = [ + migrations.AddField( + model_name='order', + name='moderated', + field=models.BooleanField(default=False, verbose_name='Модерирован'), + ), + migrations.AddField( + model_name='order', + name='published', + field=models.BooleanField(default=False, verbose_name='Опубликован'), + ), + migrations.AlterField( + model_name='order', + name='create_time', + field=models.DateTimeField(default=datetime.datetime.now, editable=False, verbose_name='Время создания'), + ), + ] diff --git a/order/migrations/0016_alter_order_email_alter_order_moderated_and_more.py b/order/migrations/0016_alter_order_email_alter_order_moderated_and_more.py new file mode 100644 index 0000000..3e84703 --- /dev/null +++ b/order/migrations/0016_alter_order_email_alter_order_moderated_and_more.py @@ -0,0 +1,38 @@ +# Generated by Django 4.1.1 on 2022-09-28 09:55 + +from django.conf import settings +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import order.models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('order', '0015_order_moderated_order_published_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='order', + name='email', + field=models.EmailField(blank=True, max_length=254, null=True, validators=[order.models._email_validate], verbose_name='Email'), + ), + migrations.AlterField( + model_name='order', + name='moderated', + field=models.BooleanField(default=True, verbose_name='Модерирован'), + ), + migrations.AlterField( + model_name='order', + name='owner', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='owner', to=settings.AUTH_USER_MODEL, verbose_name='Владелец'), + ), + migrations.AlterField( + model_name='order', + name='phone', + field=models.CharField(blank=True, max_length=16, null=True, validators=[django.core.validators.RegexValidator(regex='^\\+7[0-9]{10}$'), order.models._phone_validate], verbose_name='Телефон'), + ), + ] diff --git a/order/models.py b/order/models.py index 8af41d0..a111c6e 100644 --- a/order/models.py +++ b/order/models.py @@ -1,7 +1,10 @@ +from django.core.exceptions import * from django.core.validators import RegexValidator from django.db import models +from django.db.models import Q from account.models import SiteUser +from datetime import datetime class City(models.Model): @@ -18,6 +21,50 @@ class City(models.Model): return City.objects.order_by('name').values_list('code', 'name') +def _phone_validate(phone, order=None): + if phone is not None: + err_obj = {"phone": f'Телефон {phone} уже используется другим аккаунтом'} + if SiteUser.objects.filter(phone=phone).count() > 0: + raise ValidationError( + err_obj, + code='permission' + ) + if order is None: + if Order.objects.filter(phone=phone).count() > 0: + raise ValidationError( + err_obj, + code='permission' + ) + else: + if Order.objects.filter(~Q(id=order.id), phone=phone).count() > 0: + raise ValidationError( + err_obj, + code='permission' + ) + + +def _email_validate(email, order=None): + if email is not None: + err_obj = {'email': f'Почта {email} уже используется другим аккаунтом'} + if SiteUser.objects.filter(email=email).count(): + raise ValidationError( + err_obj, + code='permission' + ) + if order is None: + if Order.objects.filter(email=email).count() > 0: + raise ValidationError( + err_obj, + code='permission' + ) + else: + if Order.objects.filter(~Q(id=order.id), email=email).count() > 0: + raise ValidationError( + err_obj, + code='permission' + ) + + class Order(models.Model): # основные поля: название и описание name = models.CharField(max_length=200, verbose_name="Название заказа") @@ -112,13 +159,63 @@ class Order(models.Model): # примерная цена approximate_price = models.DecimalField(max_digits=12, decimal_places=2, blank=False, verbose_name="Цена") - date_start = models.DateField(blank=True, default=None, verbose_name="Дата начала") - date_end = models.DateField(blank=True, default=None, verbose_name="Дата окончания") + date_start = models.DateField(null=True, blank=True, default=None, verbose_name="Дата начала") + date_end = models.DateField(null=True, blank=True, default=None, verbose_name="Дата окончания") address_city = models.ForeignKey(City, on_delete=models.CASCADE, blank=False, related_name="address_city", verbose_name="Город") address_text = models.CharField(max_length=70, blank=True, verbose_name="Улица, дом") - owner = models.ForeignKey(SiteUser, on_delete=models.CASCADE, null=True, related_name="owner", + owner = models.ForeignKey(SiteUser, on_delete=models.CASCADE, blank=True, null=True, related_name="owner", verbose_name="Владелец") + email = models.EmailField(null=True, blank=True, verbose_name="Email") + phone = models.CharField(null=True, blank=True, max_length=16, verbose_name="Телефон", validators=[ + RegexValidator(regex="^\\+7[0-9]{10}$") + ]) + + create_time = models.DateTimeField(default=datetime.now, editable=False, verbose_name="Время создания") + + moderated = models.BooleanField(default=True, verbose_name="Модерирован") + published = models.BooleanField(default=False, verbose_name="Опубликован") + + def clean(self): + errors = {} + try: + if self.pk is None: + _phone_validate(self.phone) + else: + _phone_validate(self.phone, self) + except ValidationError as e: + errors["phone"] = [e] + + try: + if self.pk is None: + _email_validate(self.email) + else: + _email_validate(self.email, self) + except ValidationError as e: + errors["email"] = [e] + + if len(errors) > 0: + raise ValidationError(errors) + + def save(self, *args, **kwargs): + if self.pk is None: + if self.owner is None: + if self.phone is None or self.email is None: + raise Exception("Could not save: need contact information") + + if self.owner is not None: + self.phone = None + self.email = None + + self.full_clean() + + super().save(*args, **kwargs) + + def __str__(self): + return self.name + + + diff --git a/order/views.py b/order/views.py index c5ba10c..6604243 100644 --- a/order/views.py +++ b/order/views.py @@ -4,22 +4,34 @@ from .forms import * def orders_list(request): - return render(request, 'orders/orders-list.html') + if request.user.is_authenticated: + if request.user.is_staff: + orders = Order.objects.filter() + else: + orders = Order.objects.filter(published=True, moderated=True) + orders.order_by('create_time') + return render(request, 'orders/orders-list.html', {'orders': orders[:50]}) + else: + return HttpResponseRedirect('/accounts/register') def order_create(request): if request.user.is_authenticated: if request.method == 'POST': - form = BaseOrderCreationForm(request.POST) + order = Order(owner=request.user) + form = BaseOrderCreationForm(request.POST, instance=order) if form.is_valid(): - return HttpResponseRedirect('/account') + form.save() + return HttpResponseRedirect('/orders/') else: form = BaseOrderCreationForm() else: if request.method == 'POST': - form = UnregisteredUserOrderCreationForm(request.POST) + order = Order() + form = UnregisteredUserOrderCreationForm(request.POST, instance=order) if form.is_valid(): - return HttpResponseRedirect('/account') + form.save() + return HttpResponseRedirect('/dev') else: form = UnregisteredUserOrderCreationForm() print(form.visible_fields) diff --git a/static/images/test4.jpg b/static/images/test4.jpg new file mode 100644 index 0000000..11e4d17 Binary files /dev/null and b/static/images/test4.jpg differ diff --git a/static/images/test5.jpg b/static/images/test5.jpg new file mode 100644 index 0000000..4d2fe4c Binary files /dev/null and b/static/images/test5.jpg differ diff --git a/templates/orders/order-create-compleate.html b/templates/orders/order-create-compleate.html new file mode 100644 index 0000000..287bd45 --- /dev/null +++ b/templates/orders/order-create-compleate.html @@ -0,0 +1,13 @@ +{% extends 'base.html' %} +{% block title %} Аккаунт | вход {% endblock %} + +{% block content %} +
{{ order.description }}
+