Add order respondes
This commit is contained in:
parent
9a1b0f7d5a
commit
6f70716f0a
@ -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
|
||||||
|
@ -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='Заказ')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
33
order/migrations/0018_alter_orderimage_image_orderrespond.py
Normal file
33
order/migrations/0018_alter_orderimage_image_orderrespond.py
Normal 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='Пользователь')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
17
order/migrations/0019_remove_orderrespond_comment.py
Normal file
17
order/migrations/0019_remove_orderrespond_comment.py
Normal 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',
|
||||||
|
),
|
||||||
|
]
|
@ -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'),
|
||||||
|
),
|
||||||
|
]
|
@ -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)
|
||||||
|
|
||||||
|
@ -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'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
render_vars = {}
|
||||||
|
try:
|
||||||
order = Order.get_all_for_user(request.user)
|
order = Order.get_all_for_user(request.user)
|
||||||
order = order.select_related('address_city').get(id=order_id)
|
order = order.select_related('address_city').get(id=order_id)
|
||||||
images = OrderImage.objects.filter(order=order)
|
render_vars["order"] = order
|
||||||
return render(request, 'orders/order-view.html', {"order": order, "images": images})
|
|
||||||
|
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}')
|
||||||
|
@ -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>
|
||||||
|
23
templates/orders/order-respond.html
Normal file
23
templates/orders/order-respond.html
Normal 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 %}
|
@ -15,10 +15,17 @@
|
|||||||
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 %}
|
||||||
|
{% if order %}
|
||||||
<h1 class=deprecated-page-header"> Заказ {{ order.name }} </h1>
|
<h1 class=deprecated-page-header"> Заказ {{ order.name }} </h1>
|
||||||
|
|
||||||
<div class="field-wrapper">
|
<div class="field-wrapper">
|
||||||
@ -42,4 +49,33 @@
|
|||||||
<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 %}
|
||||||
|
@ -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 %}
|
|
Reference in New Issue
Block a user