Add order respondes

This commit is contained in:
vlados31 2022-10-03 01:41:53 +03:00
parent 9a1b0f7d5a
commit 6f70716f0a
12 changed files with 258 additions and 50 deletions

View File

@ -17,3 +17,8 @@ class OrderAdmin(admin.ModelAdmin):
@admin.register(OrderImage) @admin.register(OrderImage)
class OrderImageAdmin(admin.ModelAdmin): class OrderImageAdmin(admin.ModelAdmin):
pass pass
@admin.register(OrderRespond)
class OrderRespondAdmin(admin.ModelAdmin):
pass

View File

@ -0,0 +1,33 @@
# Generated by Django 4.1.1 on 2022-09-29 22:54
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('order', '0016_alter_order_email_alter_order_moderated_and_more'),
]
operations = [
migrations.AlterField(
model_name='order',
name='email',
field=models.EmailField(blank=True, max_length=254, null=True, verbose_name='Email'),
),
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}$')], verbose_name='Телефон'),
),
migrations.CreateModel(
name='OrderImage',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('image', models.ImageField(height_field=1080, upload_to='media/order-images', verbose_name='Картинка', width_field=1920)),
('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='order', to='order.order', verbose_name='Заказ')),
],
),
]

View File

@ -0,0 +1,33 @@
# Generated by Django 4.1.1 on 2022-10-02 15:39
import datetime
from django.conf import settings
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', '0017_alter_order_email_alter_order_phone_orderimage'),
]
operations = [
migrations.AlterField(
model_name='orderimage',
name='image',
field=models.ImageField(upload_to=order.models._upload_image_filename, verbose_name='Картинка'),
),
migrations.CreateModel(
name='OrderRespond',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=datetime.datetime.now, editable=False, verbose_name='Время отклика')),
('comment', models.CharField(blank=True, default='', max_length=200, verbose_name='Коммент')),
('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='respond_order', to='order.order', verbose_name='Заказ')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='respond_user', to=settings.AUTH_USER_MODEL, verbose_name='Пользователь')),
],
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 4.1.1 on 2022-10-02 15:55
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('order', '0018_alter_orderimage_image_orderrespond'),
]
operations = [
migrations.RemoveField(
model_name='orderrespond',
name='comment',
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 4.1.1 on 2022-10-02 20:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('order', '0019_remove_orderrespond_comment'),
]
operations = [
migrations.AddConstraint(
model_name='orderrespond',
constraint=models.UniqueConstraint(fields=('user', 'order'), name='unique_order_respond_user_order'),
),
]

View File

@ -251,3 +251,26 @@ class OrderImage(models.Model):
return f"{self.id}: {self.order}" return f"{self.id}: {self.order}"
class OrderRespond(models.Model):
create_time = models.DateTimeField(default=datetime.now, editable=False, verbose_name="Время отклика")
user = models.ForeignKey(SiteUser, on_delete=models.CASCADE, related_name="respond_user", verbose_name="Пользователь")
order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name="respond_order", verbose_name="Заказ")
class Meta:
constraints = [
models.UniqueConstraint(
fields=['user', 'order'], name='unique_order_respond_user_order'
)
]
def __str__(self):
return f"{self.order}: {self.user}"
def save(self, *args, **kwargs):
if Order.objects.get(id=self.order.id) == self.user.id:
raise Exception("User can't respond to self order")
self.full_clean()
super().save(*args, **kwargs)

View File

@ -21,5 +21,6 @@ urlpatterns = [
path('', views.orders_list, name='orders-list'), path('', views.orders_list, name='orders-list'),
path('create', views.order_create, name='order-create'), path('create', views.order_create, name='order-create'),
path('view/<int:order_id>', views.order_view, name='order-view'), path('view/<int:order_id>', views.order_view, name='order-view'),
path('respond/<int:order_id>', views.order_respond, name='order-respond'),
] ]

View File

@ -1,5 +1,9 @@
import traceback
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import render from django.shortcuts import render
from django.urls import reverse
from .forms import * from .forms import *
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
@ -37,7 +41,49 @@ def order_create(request):
@login_required @login_required
def order_view(request, order_id): def order_view(request, order_id):
order = Order.get_all_for_user(request.user) render_vars = {}
order = order.select_related('address_city').get(id=order_id) try:
images = OrderImage.objects.filter(order=order) order = Order.get_all_for_user(request.user)
return render(request, 'orders/order-view.html', {"order": order, "images": images}) order = order.select_related('address_city').get(id=order_id)
render_vars["order"] = order
render_vars["images"] = OrderImage.objects.filter(order=order)
render_vars["can_responde"] = order.owner_id != request.user.id
if render_vars["can_responde"]:
render_vars["respondes_count"] = OrderRespond.objects.filter(order_id=order_id).count()
render_vars["is_responde"] = OrderRespond.objects.filter(user_id=request.user.id, order_id=order_id).count() > 0
render_vars["respond_users"] = OrderRespond.objects.filter(order_id=order_id).\
select_related('user').order_by('create_time')
except Exception:
traceback.print_exc()
render_vars["order"] = None
return render(request, 'orders/order-view.html', render_vars)
@login_required
def order_respond(request, order_id):
try:
if request.method == 'POST':
action = None
if "action" in request.POST:
action = request.POST["action"]
else:
print("order_respond: no action param found!")
if action == "respond":
r = OrderRespond(order_id=order_id, user=request.user)
r.save()
print("order_respond: save respond!")
if action == "unrespond":
OrderRespond.objects.filter(order_id=order_id, user=request.user).delete()
except Exception:
traceback.print_exc()
return HttpResponseRedirect(f'/orders/view/{order_id}')

View File

@ -49,13 +49,13 @@
<div class="dropdown-content"> <div class="dropdown-content">
{% if user.is_authenticated %} {% if user.is_authenticated %}
<a href="{% url 'profile' %}">Профиль</a> <a href="{% url 'profile' %}">Профиль</a>
<a href="#">Мои заказы</a> <a href="{% url 'my-orders' %}">Мои заказы</a>
<a href="#">Мой кошелёк</a> <a href="#">Мой кошелёк</a>
<a href="#">Мои записи</a> <a href="#">Мои записи</a>
<a href="{% url 'logout'%}?next={{request.path}}">Выход</a> <a href="{% url 'logout'%}?next={{request.path}}">Выход</a>
{% else %} {% else %}
<span>Вы не вошли</span> <span>Вы не вошли</span>
<a href="{% url 'login'%}?next={{request.path}}">Вход</a> <a href="{% url 'login' %}?next={{request.path}}">Вход</a>
<a href="{% url 'register' %}?next={{request.path}}">Регистрация</a> <a href="{% url 'register' %}?next={{request.path}}">Регистрация</a>
{% endif %} {% endif %}
</div> </div>

View File

@ -0,0 +1,23 @@
{% extends 'base.html' %}
{% block title %} Аккаунт | вход {% endblock %}
{% block styles %}
<style>
.field-wrapper {
margin: 1em;
padding: 1em;
border-left: var(--brand-color) solid 1px;
}
.field-wrapper > * {
display: inline;
}
.field-wrapper > span {
font-weight: bolder;
margin-right: 1em;
}
</style>
{% endblock %}
{% block content %}
{% endblock %}

View File

@ -15,31 +15,67 @@
font-weight: bolder; font-weight: bolder;
margin-right: 1em; margin-right: 1em;
} }
.respond-user {
border-left: 1px dashed violet;
margin: 2em;
padding-left: 1em;
}
</style> </style>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h1 class=deprecated-page-header"> Заказ {{ order.name }} </h1> {% if order %}
<h1 class=deprecated-page-header"> Заказ {{ order.name }} </h1>
<div class="field-wrapper"> <div class="field-wrapper">
{% for i in images %} {% for i in images %}
<img src="{{ i.image.url }}" alt="image-{{ i.id }}"> <img src="{{ i.image.url }}" alt="image-{{ i.id }}">
{% endfor %} {% endfor %}
</div> </div>
<div class="field-wrapper"> <div class="field-wrapper">
<span>Описание:</span> <span>Описание:</span>
<p>{{ order.description }}</p> <p>{{ order.description }}</p>
</div> </div>
<div class="field-wrapper"> <div class="field-wrapper">
<span>Дата создания:</span> <span>Дата создания:</span>
<p>{{ order.create_time }}</p> <p>{{ order.create_time }}</p>
</div> </div>
<div class="field-wrapper"> <div class="field-wrapper">
<span>Город:</span> <span>Город:</span>
<p>{{ order.address_city.name }}</p> <p>{{ order.address_city.name }}</p>
</div> </div>
{% if can_responde %}
{% if is_responde %}
<form action="{% url 'order-respond' order.id %}" method="POST">
{% csrf_token %}
<input type="hidden" name="action" value="unrespond">
<input type="submit" value="Отменить отклик">
</form>
{% else %}
<form action="{% url 'order-respond' order.id %}" method="POST">
{% csrf_token %}
<input type="hidden" name="action" value="respond">
<input type="submit" value="Откликнуться!">
</form>
{% endif %}
<p> Откликнулось человек: {{ respondes_count }} </p>
{% else %}
<p>
Вы владелец объявления. {% if respond_users %}Вот эти пользователи откликнулись на ваше объявление:{% else %}Пока на него нет откликов.{% endif %}
</p>
{% for r in respond_users %}
<div class="respond-user">
{{ r.create_time }}: {{ r.user.name }}
</div>
{% endfor %}
{% endif %}
{% else %}
<h1 class=deprecated-page-header"> Запрошенный вами заказ не найден! </h1>
{% endif %}
{% endblock %} {% endblock %}

View File

@ -1,26 +0,0 @@
{% extends 'base.html' %}
{% block title %} Аккаунт | вход {% endblock %}
{% block content %}
<h1 class=deprecated-page-header"> Ваш аккаунт </h1>
{% if user.is_authenticated %}
Ваше имя: {{ user.name }}<br>
Ваша фамилия: {{ user.surname }}<br>
Ваша почта: {{ user.email }}<br>
Ваш телефон: {{ user.phone }}<br>
Ваш телефон верифицирован:
{% if user.is_phone_verified %}
<span style="color: green">Да</span>
{% else %}
<span style="color: red">Нет</span>
{% endif %}<br>
{% if user.is_staff %}
<span style="color: green">Вам разрешено входить в административную часть сайта</span>
<br>
{% endif %}
{% else %}
Вы не вошли. Используйте меню аккаунта для входа или авторизации.
{% endif %}
{% endblock %}