Merge remote-tracking branch 'origin/develop' into feature/authorization
This commit is contained in:
commit
3c7fc7a436
|
|
@ -18,7 +18,7 @@ class UserAdmin(BaseUserAdmin):
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, {'fields': ('email', 'password',)}),
|
(None, {'fields': ('email', 'password',)}),
|
||||||
(_('Personal info'), {
|
(_('Personal info'), {
|
||||||
'fields': ('username', 'first_name', 'last_name', )}),
|
'fields': ('username', 'first_name', 'last_name', 'image')}),
|
||||||
(_('Subscription'), {
|
(_('Subscription'), {
|
||||||
'fields': (
|
'fields': (
|
||||||
'newsletter',
|
'newsletter',
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
"""Establishment admin conf."""
|
"""Establishment admin conf."""
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from establishment import models
|
|
||||||
from django.contrib.contenttypes.admin import GenericTabularInline
|
from django.contrib.contenttypes.admin import GenericTabularInline
|
||||||
|
from establishment import models
|
||||||
from main.models import Award, MetaDataContent
|
from main.models import Award, MetaDataContent
|
||||||
|
from review import models as review_models
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.EstablishmentType)
|
@admin.register(models.EstablishmentType)
|
||||||
|
|
@ -25,12 +27,63 @@ class MetaDataContentInline(GenericTabularInline):
|
||||||
extra = 0
|
extra = 0
|
||||||
|
|
||||||
|
|
||||||
|
class ContactPhoneInline(admin.TabularInline):
|
||||||
|
"""Contact phone inline admin."""
|
||||||
|
model = models.ContactPhone
|
||||||
|
extra = 0
|
||||||
|
|
||||||
|
|
||||||
|
class ContactEmailInline(admin.TabularInline):
|
||||||
|
"""Contact email inline admin."""
|
||||||
|
model = models.ContactEmail
|
||||||
|
extra = 0
|
||||||
|
|
||||||
|
|
||||||
|
class ReviewInline(GenericTabularInline):
|
||||||
|
model = review_models.Review
|
||||||
|
extra = 0
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.Establishment)
|
@admin.register(models.Establishment)
|
||||||
class EstablishmentAdmin(admin.ModelAdmin):
|
class EstablishmentAdmin(admin.ModelAdmin):
|
||||||
"""Establishment admin."""
|
"""Establishment admin."""
|
||||||
inlines = [AwardInline, MetaDataContentInline]
|
inlines = [
|
||||||
|
AwardInline, MetaDataContentInline,
|
||||||
|
ContactPhoneInline, ContactEmailInline,
|
||||||
|
ReviewInline]
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.EstablishmentSchedule)
|
@admin.register(models.EstablishmentSchedule)
|
||||||
class EstablishmentSchedule(admin.ModelAdmin):
|
class EstablishmentSchedule(admin.ModelAdmin):
|
||||||
"""Establishment schedule"""
|
"""Establishment schedule"""
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(models.Comment)
|
||||||
|
class EstablishmentComment(admin.ModelAdmin):
|
||||||
|
"""Establishment comments."""
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(models.Position)
|
||||||
|
class PositionAdmin(admin.ModelAdmin):
|
||||||
|
"""Position admin."""
|
||||||
|
|
||||||
|
|
||||||
|
class PlateInline(admin.TabularInline):
|
||||||
|
"""Plate inline admin"""
|
||||||
|
model = models.Plate
|
||||||
|
extra = 0
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(models.Menu)
|
||||||
|
class MenuAdmin(admin.ModelAdmin):
|
||||||
|
"""Menu admin."""
|
||||||
|
list_display = ['id', 'category_translated']
|
||||||
|
inlines = [
|
||||||
|
PlateInline,
|
||||||
|
]
|
||||||
|
|
||||||
|
def category_translated(self, obj):
|
||||||
|
"""Get user's short name."""
|
||||||
|
return obj.category_translated
|
||||||
|
|
||||||
|
category_translated.short_description = _('category')
|
||||||
77
apps/establishment/migrations/0005_auto_20190901_0831.py
Normal file
77
apps/establishment/migrations/0005_auto_20190901_0831.py
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 08:31
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import phonenumber_field.modelfields
|
||||||
|
import utils.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('location', '0009_auto_20190901_0831'),
|
||||||
|
('establishment', '0004_auto_20190828_1156'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Contact',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('address', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='location.Address')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'contact',
|
||||||
|
'verbose_name_plural': 'contacts',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='establishment',
|
||||||
|
name='description',
|
||||||
|
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='Description'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='establishment',
|
||||||
|
name='name',
|
||||||
|
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='Name'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='establishmentsubtype',
|
||||||
|
name='name',
|
||||||
|
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='Description'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='establishmenttype',
|
||||||
|
name='name',
|
||||||
|
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='Description'),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='ContactPhone',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('phone', phonenumber_field.modelfields.PhoneNumberField(max_length=128)),
|
||||||
|
('contact', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='phones', to='establishment.Contact')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'contact phone',
|
||||||
|
'verbose_name_plural': 'contact phones',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='ContactEmail',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('email', models.EmailField(max_length=254)),
|
||||||
|
('contact', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='emails', to='establishment.Contact')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'contact email',
|
||||||
|
'verbose_name_plural': 'contact emails',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='contact',
|
||||||
|
name='establishment',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contacts', to='establishment.Establishment'),
|
||||||
|
),
|
||||||
|
]
|
||||||
32
apps/establishment/migrations/0006_comment.py
Normal file
32
apps/establishment/migrations/0006_comment.py
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 09:16
|
||||||
|
|
||||||
|
import django.utils.timezone
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('establishment', '0005_establishmentschedule'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Comment',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('created', models.DateTimeField(default=django.utils.timezone.now, editable=False, verbose_name='Date created')),
|
||||||
|
('modified', models.DateTimeField(auto_now=True, verbose_name='Date updated')),
|
||||||
|
('text', models.TextField(verbose_name='Comment text')),
|
||||||
|
('mark', models.PositiveIntegerField(blank=True, default=None, null=True, verbose_name='Mark')),
|
||||||
|
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to=settings.AUTH_USER_MODEL, verbose_name='Author')),
|
||||||
|
('establishment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='establishment.Establishment', verbose_name='Establishment')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Comment',
|
||||||
|
'verbose_name_plural': 'Comments',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
14
apps/establishment/migrations/0006_merge_20190901_0846.py
Normal file
14
apps/establishment/migrations/0006_merge_20190901_0846.py
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 08:46
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0005_auto_20190901_0831'),
|
||||||
|
('establishment', '0005_establishmentschedule'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
]
|
||||||
30
apps/establishment/migrations/0007_auto_20190901_1032.py
Normal file
30
apps/establishment/migrations/0007_auto_20190901_1032.py
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 10:32
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0006_merge_20190901_0846'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='contactemail',
|
||||||
|
name='contact',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='contactphone',
|
||||||
|
name='contact',
|
||||||
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='Contact',
|
||||||
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='ContactEmail',
|
||||||
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='ContactPhone',
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 10:36
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import phonenumber_field.modelfields
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0007_auto_20190901_1032'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='ContactPhone',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('phone', phonenumber_field.modelfields.PhoneNumberField(max_length=128)),
|
||||||
|
('establishment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='phones', to='establishment.Establishment')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'contact phone',
|
||||||
|
'verbose_name_plural': 'contact phones',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='ContactEmail',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('email', models.EmailField(max_length=254)),
|
||||||
|
('establishment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='emails', to='establishment.Establishment')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'contact email',
|
||||||
|
'verbose_name_plural': 'contact emails',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
14
apps/establishment/migrations/0009_merge_20190901_1131.py
Normal file
14
apps/establishment/migrations/0009_merge_20190901_1131.py
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 11:31
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0006_comment'),
|
||||||
|
('establishment', '0008_contactemail_contactphone'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
]
|
||||||
81
apps/establishment/migrations/0010_auto_20190901_1142.py
Normal file
81
apps/establishment/migrations/0010_auto_20190901_1142.py
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 11:42
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
import utils.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('establishment', '0009_merge_20190901_1131'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Employee',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('created', models.DateTimeField(default=django.utils.timezone.now, editable=False, verbose_name='Date created')),
|
||||||
|
('modified', models.DateTimeField(auto_now=True, verbose_name='Date updated')),
|
||||||
|
('name', models.CharField(max_length=255, verbose_name='Last name')),
|
||||||
|
('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='employee_records_created', to=settings.AUTH_USER_MODEL, verbose_name='created by')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Employee',
|
||||||
|
'verbose_name_plural': 'Employees',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Position',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('created', models.DateTimeField(default=django.utils.timezone.now, editable=False, verbose_name='Date created')),
|
||||||
|
('modified', models.DateTimeField(auto_now=True, verbose_name='Date updated')),
|
||||||
|
('name', utils.models.TJSONField(blank=True, default=None, help_text='{"en":"some text"}', null=True, verbose_name='Description')),
|
||||||
|
('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='position_records_created', to=settings.AUTH_USER_MODEL, verbose_name='created by')),
|
||||||
|
('modified_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='position_records_modified', to=settings.AUTH_USER_MODEL, verbose_name='modified by')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Position',
|
||||||
|
'verbose_name_plural': 'Positions',
|
||||||
|
},
|
||||||
|
bases=(models.Model, utils.models.TraslatedFieldsMixin),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='EstablishmentEmployee',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('created', models.DateTimeField(default=django.utils.timezone.now, editable=False, verbose_name='Date created')),
|
||||||
|
('modified', models.DateTimeField(auto_now=True, verbose_name='Date updated')),
|
||||||
|
('from_date', models.DateTimeField(default=django.utils.timezone.now, verbose_name='From date')),
|
||||||
|
('to_date', models.DateTimeField(blank=True, default=None, null=True, verbose_name='To date')),
|
||||||
|
('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='establishmentemployee_records_created', to=settings.AUTH_USER_MODEL, verbose_name='created by')),
|
||||||
|
('employee', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='establishment.Employee', verbose_name='Employee')),
|
||||||
|
('establishment', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='establishment.Establishment', verbose_name='Establishment')),
|
||||||
|
('modified_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='establishmentemployee_records_modified', to=settings.AUTH_USER_MODEL, verbose_name='modified by')),
|
||||||
|
('position', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='establishment.Position', verbose_name='Position')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='employee',
|
||||||
|
name='establishments',
|
||||||
|
field=models.ManyToManyField(related_name='employees', through='establishment.EstablishmentEmployee', to='establishment.Establishment'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='employee',
|
||||||
|
name='modified_by',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='employee_records_modified', to=settings.AUTH_USER_MODEL, verbose_name='modified by'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='employee',
|
||||||
|
name='user',
|
||||||
|
field=models.OneToOneField(blank=True, default=None, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL, verbose_name='User'),
|
||||||
|
),
|
||||||
|
]
|
||||||
53
apps/establishment/migrations/0011_menu_plate.py
Normal file
53
apps/establishment/migrations/0011_menu_plate.py
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 12:11
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
import utils.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('main', '0013_auto_20190901_1032'),
|
||||||
|
('establishment', '0010_auto_20190901_1142'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Menu',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('created', models.DateTimeField(default=django.utils.timezone.now, editable=False, verbose_name='Date created')),
|
||||||
|
('modified', models.DateTimeField(auto_now=True, verbose_name='Date updated')),
|
||||||
|
('category', utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='name')),
|
||||||
|
('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='menu_records_created', to=settings.AUTH_USER_MODEL, verbose_name='created by')),
|
||||||
|
('establishment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='establishment.Establishment', verbose_name='establishment')),
|
||||||
|
('modified_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='menu_records_modified', to=settings.AUTH_USER_MODEL, verbose_name='modified by')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'menu',
|
||||||
|
'verbose_name_plural': 'menu',
|
||||||
|
},
|
||||||
|
bases=(utils.models.TraslatedFieldsMixin, models.Model),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Plate',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='name')),
|
||||||
|
('description', utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='description')),
|
||||||
|
('price', models.DecimalField(decimal_places=2, max_digits=14, verbose_name='price')),
|
||||||
|
('is_signature_plate', models.BooleanField(verbose_name='is signature plate')),
|
||||||
|
('currency', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.Currency', verbose_name='currency')),
|
||||||
|
('menu', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='establishment.Menu', verbose_name='menu')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'plate',
|
||||||
|
'verbose_name_plural': 'plates',
|
||||||
|
},
|
||||||
|
bases=(utils.models.TraslatedFieldsMixin, models.Model),
|
||||||
|
),
|
||||||
|
]
|
||||||
19
apps/establishment/migrations/0012_auto_20190901_1251.py
Normal file
19
apps/establishment/migrations/0012_auto_20190901_1251.py
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 12:51
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
import utils.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0011_menu_plate'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='menu',
|
||||||
|
name='category',
|
||||||
|
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='category'),
|
||||||
|
),
|
||||||
|
]
|
||||||
33
apps/establishment/migrations/0013_auto_20190901_1428.py
Normal file
33
apps/establishment/migrations/0013_auto_20190901_1428.py
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 14:28
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0012_auto_20190901_1251'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='establishment',
|
||||||
|
name='booking',
|
||||||
|
field=models.URLField(blank=True, default=None, null=True, verbose_name='Booking URL'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='establishment',
|
||||||
|
name='facebook',
|
||||||
|
field=models.URLField(blank=True, default=None, null=True, verbose_name='Facebook URL'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='establishment',
|
||||||
|
name='lafourchette',
|
||||||
|
field=models.URLField(blank=True, default=None, null=True, verbose_name='Lafourchette URL'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='establishment',
|
||||||
|
name='twitter',
|
||||||
|
field=models.URLField(blank=True, default=None, null=True, verbose_name='Twitter URL'),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
apps/establishment/migrations/0014_establishment_website.py
Normal file
18
apps/establishment/migrations/0014_establishment_website.py
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 14:48
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0013_auto_20190901_1428'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='establishment',
|
||||||
|
name='website',
|
||||||
|
field=models.URLField(blank=True, default=None, null=True, verbose_name='Web site URL'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -1,12 +1,16 @@
|
||||||
"""Establishment models."""
|
"""Establishment models."""
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
|
||||||
|
from django.contrib.contenttypes import fields as generic
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.utils import timezone
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from phonenumber_field.modelfields import PhoneNumberField
|
||||||
|
|
||||||
from location.models import Address
|
from location.models import Address
|
||||||
from utils.models import (ProjectBaseMixin, ImageMixin, TJSONField,
|
from utils.models import (ProjectBaseMixin, ImageMixin, TJSONField,
|
||||||
TraslatedFieldsMixin, BaseAttributes)
|
TraslatedFieldsMixin, BaseAttributes)
|
||||||
from django.contrib.contenttypes import fields as generic
|
|
||||||
|
|
||||||
|
|
||||||
# todo: establishment type&subtypes check
|
# todo: establishment type&subtypes check
|
||||||
|
|
@ -14,7 +18,7 @@ class EstablishmentType(ProjectBaseMixin, TraslatedFieldsMixin):
|
||||||
"""Establishment type model."""
|
"""Establishment type model."""
|
||||||
|
|
||||||
name = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'),
|
name = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'),
|
||||||
help_text='{"en":"some text"}')
|
help_text='{"en-GB":"some text"}')
|
||||||
use_subtypes = models.BooleanField(_('Use subtypes'), default=True)
|
use_subtypes = models.BooleanField(_('Use subtypes'), default=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
@ -38,7 +42,7 @@ class EstablishmentSubType(ProjectBaseMixin, TraslatedFieldsMixin):
|
||||||
"""Establishment type model."""
|
"""Establishment type model."""
|
||||||
|
|
||||||
name = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'),
|
name = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'),
|
||||||
help_text='{"en":"some text"}')
|
help_text='{"en-GB":"some text"}')
|
||||||
establishment_type = models.ForeignKey(EstablishmentType,
|
establishment_type = models.ForeignKey(EstablishmentType,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
verbose_name=_('Type'))
|
verbose_name=_('Type'))
|
||||||
|
|
@ -70,15 +74,27 @@ class EstablishmentQuerySet(models.QuerySet):
|
||||||
else:
|
else:
|
||||||
return self.none()
|
return self.none()
|
||||||
|
|
||||||
|
def by_country_code(self, code):
|
||||||
|
"""Return establishments by country code"""
|
||||||
|
return self.filter(address__city__country__code=code)
|
||||||
|
|
||||||
|
def prefetch_actual_employees(self):
|
||||||
|
"""Prefetch actual employees."""
|
||||||
|
return self.prefetch_related(
|
||||||
|
models.Prefetch('establishmentemployee_set',
|
||||||
|
queryset=EstablishmentEmployee.objects.actual().select_related(
|
||||||
|
'position'),
|
||||||
|
to_attr='actual_establishment_employees'))
|
||||||
|
|
||||||
|
|
||||||
class Establishment(ProjectBaseMixin, ImageMixin, TraslatedFieldsMixin):
|
class Establishment(ProjectBaseMixin, ImageMixin, TraslatedFieldsMixin):
|
||||||
"""Establishment model."""
|
"""Establishment model."""
|
||||||
|
|
||||||
name = TJSONField(blank=True, null=True, default=None,
|
name = TJSONField(blank=True, null=True, default=None,
|
||||||
verbose_name=_('Name'), help_text='{"en":"some text"}')
|
verbose_name=_('Name'), help_text='{"en-GB":"some text"}')
|
||||||
description = TJSONField(blank=True, null=True, default=None,
|
description = TJSONField(blank=True, null=True, default=None,
|
||||||
verbose_name=_('Description'),
|
verbose_name=_('Description'),
|
||||||
help_text='{"en":"some text"}')
|
help_text='{"en-GB":"some text"}')
|
||||||
public_mark = models.PositiveIntegerField(blank=True, null=True,
|
public_mark = models.PositiveIntegerField(blank=True, null=True,
|
||||||
default=None,
|
default=None,
|
||||||
verbose_name=_('Public mark'),)
|
verbose_name=_('Public mark'),)
|
||||||
|
|
@ -98,8 +114,19 @@ class Establishment(ProjectBaseMixin, ImageMixin, TraslatedFieldsMixin):
|
||||||
price_level = models.PositiveIntegerField(blank=True, null=True,
|
price_level = models.PositiveIntegerField(blank=True, null=True,
|
||||||
default=None,
|
default=None,
|
||||||
verbose_name=_('Price level'))
|
verbose_name=_('Price level'))
|
||||||
|
website = models.URLField(blank=True, null=True, default=None,
|
||||||
|
verbose_name=_('Web site URL'))
|
||||||
|
facebook = models.URLField(blank=True, null=True, default=None,
|
||||||
|
verbose_name=_('Facebook URL'))
|
||||||
|
twitter = models.URLField(blank=True, null=True, default=None,
|
||||||
|
verbose_name=_('Twitter URL'))
|
||||||
|
lafourchette = models.URLField(blank=True, null=True, default=None,
|
||||||
|
verbose_name=_('Lafourchette URL'))
|
||||||
|
booking = models.URLField(blank=True, null=True, default=None,
|
||||||
|
verbose_name=_('Booking URL'))
|
||||||
awards = generic.GenericRelation(to='main.Award')
|
awards = generic.GenericRelation(to='main.Award')
|
||||||
tags = generic.GenericRelation(to='main.MetaDataContent')
|
tags = generic.GenericRelation(to='main.MetaDataContent')
|
||||||
|
reviews = generic.GenericRelation(to='review.Review')
|
||||||
|
|
||||||
objects = EstablishmentQuerySet.as_manager()
|
objects = EstablishmentQuerySet.as_manager()
|
||||||
|
|
||||||
|
|
@ -123,6 +150,7 @@ class Establishment(ProjectBaseMixin, ImageMixin, TraslatedFieldsMixin):
|
||||||
country = self.address.city.country
|
country = self.address.city.country
|
||||||
return country.low_price, country.high_price
|
return country.low_price, country.high_price
|
||||||
|
|
||||||
|
# todo: make via prefetch
|
||||||
@property
|
@property
|
||||||
def subtypes(self):
|
def subtypes(self):
|
||||||
return EstablishmentSubType.objects.filter(
|
return EstablishmentSubType.objects.filter(
|
||||||
|
|
@ -140,6 +168,73 @@ class Establishment(ProjectBaseMixin, ImageMixin, TraslatedFieldsMixin):
|
||||||
raise ValidationError('Establishment type of subtype does not match')
|
raise ValidationError('Establishment type of subtype does not match')
|
||||||
self.establishment_subtypes.add(establishment_subtype)
|
self.establishment_subtypes.add(establishment_subtype)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def best_price_menu(self):
|
||||||
|
return 150
|
||||||
|
|
||||||
|
@property
|
||||||
|
def best_price_carte(self):
|
||||||
|
return 200
|
||||||
|
|
||||||
|
|
||||||
|
class Position(BaseAttributes, TraslatedFieldsMixin):
|
||||||
|
"""Position model."""
|
||||||
|
|
||||||
|
name = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'),
|
||||||
|
help_text='{"en":"some text"}')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta class."""
|
||||||
|
|
||||||
|
verbose_name = _('Position')
|
||||||
|
verbose_name_plural = _('Positions')
|
||||||
|
|
||||||
|
|
||||||
|
class EstablishmentEmployeeQuerySet(models.QuerySet):
|
||||||
|
"""Extended queryset for EstablishmEntemployee model."""
|
||||||
|
|
||||||
|
def actual(self):
|
||||||
|
"""Actual objects.."""
|
||||||
|
now = timezone.now()
|
||||||
|
return self.filter(models.Q(from_date__lte=now),
|
||||||
|
(models.Q(to_date__gte=now) |
|
||||||
|
models.Q(to_date__isnull=True)))
|
||||||
|
|
||||||
|
|
||||||
|
class EstablishmentEmployee(BaseAttributes):
|
||||||
|
"""EstablishmentEmployee model."""
|
||||||
|
|
||||||
|
establishment = models.ForeignKey(Establishment, on_delete=models.PROTECT,
|
||||||
|
verbose_name=_('Establishment'))
|
||||||
|
employee = models.ForeignKey('establishment.Employee', on_delete=models.PROTECT,
|
||||||
|
verbose_name=_('Employee'))
|
||||||
|
from_date = models.DateTimeField(default=timezone.now, verbose_name=_('From date'))
|
||||||
|
to_date = models.DateTimeField(blank=True, null=True, default=None,
|
||||||
|
verbose_name=_('To date'))
|
||||||
|
position = models.ForeignKey(Position, on_delete=models.PROTECT,
|
||||||
|
verbose_name=_('Position'))
|
||||||
|
|
||||||
|
objects = EstablishmentEmployeeQuerySet.as_manager()
|
||||||
|
|
||||||
|
|
||||||
|
class Employee(BaseAttributes):
|
||||||
|
"""Employee model."""
|
||||||
|
|
||||||
|
user = models.OneToOneField('account.User', on_delete=models.PROTECT,
|
||||||
|
null=True, blank=True, default=None,
|
||||||
|
verbose_name=_('User'))
|
||||||
|
name = models.CharField(max_length=255, verbose_name=_('Last name'))
|
||||||
|
establishments = models.ManyToManyField(Establishment, related_name='employees',
|
||||||
|
through=EstablishmentEmployee)
|
||||||
|
awards = generic.GenericRelation(to='main.Award')
|
||||||
|
tags = generic.GenericRelation(to='main.MetaDataContent')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta class."""
|
||||||
|
|
||||||
|
verbose_name = _('Employee')
|
||||||
|
verbose_name_plural = _('Employees')
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentScheduleQuerySet(models.QuerySet):
|
class EstablishmentScheduleQuerySet(models.QuerySet):
|
||||||
"""QuerySet for model EstablishmentSchedule"""
|
"""QuerySet for model EstablishmentSchedule"""
|
||||||
|
|
@ -160,3 +255,124 @@ class EstablishmentSchedule(BaseAttributes):
|
||||||
"""Meta class"""
|
"""Meta class"""
|
||||||
verbose_name = _('Establishment schedule')
|
verbose_name = _('Establishment schedule')
|
||||||
verbose_name_plural = _('Establishment schedules')
|
verbose_name_plural = _('Establishment schedules')
|
||||||
|
|
||||||
|
|
||||||
|
class ContactPhone(models.Model):
|
||||||
|
"""Contact phone model."""
|
||||||
|
establishment = models.ForeignKey(
|
||||||
|
Establishment, related_name='phones', on_delete=models.CASCADE)
|
||||||
|
phone = PhoneNumberField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _('contact phone')
|
||||||
|
verbose_name_plural = _('contact phones')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'{self.phone.as_e164}'
|
||||||
|
|
||||||
|
|
||||||
|
class ContactEmail(models.Model):
|
||||||
|
"""Contact email model."""
|
||||||
|
establishment = models.ForeignKey(
|
||||||
|
Establishment, related_name='emails', on_delete=models.CASCADE)
|
||||||
|
email = models.EmailField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _('contact email')
|
||||||
|
verbose_name_plural = _('contact emails')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'{self.email}'
|
||||||
|
|
||||||
|
#
|
||||||
|
# class Wine(TraslatedFieldsMixin, models.Model):
|
||||||
|
# """Wine model."""
|
||||||
|
# establishment = models.ForeignKey(
|
||||||
|
# 'establishment.Establishment', verbose_name=_('establishment'),
|
||||||
|
# on_delete=models.CASCADE)
|
||||||
|
# bottles = models.IntegerField(_('bottles'))
|
||||||
|
# price_min = models.DecimalField(
|
||||||
|
# _('price min'), max_digits=14, decimal_places=2)
|
||||||
|
# price_max = models.DecimalField(
|
||||||
|
# _('price max'), max_digits=14, decimal_places=2)
|
||||||
|
# by_glass = models.BooleanField(_('by glass'))
|
||||||
|
# price_glass_min = models.DecimalField(
|
||||||
|
# _('price min'), max_digits=14, decimal_places=2)
|
||||||
|
# price_glass_max = models.DecimalField(
|
||||||
|
# _('price max'), max_digits=14, decimal_places=2)
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
class Plate(TraslatedFieldsMixin, models.Model):
|
||||||
|
"""Plate model."""
|
||||||
|
|
||||||
|
name = TJSONField(
|
||||||
|
blank=True, null=True, default=None, verbose_name=_('name'),
|
||||||
|
help_text='{"en-GB":"some text"}')
|
||||||
|
description = TJSONField(
|
||||||
|
blank=True, null=True, default=None, verbose_name=_('description'),
|
||||||
|
help_text='{"en-GB":"some text"}')
|
||||||
|
price = models.DecimalField(
|
||||||
|
_('price'), max_digits=14, decimal_places=2)
|
||||||
|
is_signature_plate = models.BooleanField(_('is signature plate'))
|
||||||
|
currency = models.ForeignKey(
|
||||||
|
'main.Currency', verbose_name=_('currency'), on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
menu = models.ForeignKey(
|
||||||
|
'establishment.Menu', verbose_name=_('menu'), on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _('plate')
|
||||||
|
verbose_name_plural = _('plates')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'plate_id:{self.id}'
|
||||||
|
|
||||||
|
|
||||||
|
class Menu(TraslatedFieldsMixin, BaseAttributes):
|
||||||
|
"""Menu model."""
|
||||||
|
category = TJSONField(
|
||||||
|
blank=True, null=True, default=None, verbose_name=_('category'),
|
||||||
|
help_text='{"en-GB":"some text"}')
|
||||||
|
establishment = models.ForeignKey(
|
||||||
|
'establishment.Establishment', verbose_name=_('establishment'),
|
||||||
|
on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _('menu')
|
||||||
|
verbose_name_plural = _('menu')
|
||||||
|
|
||||||
|
|
||||||
|
class CommentQuerySet(models.QuerySet):
|
||||||
|
"""QuerySets for Comment model."""
|
||||||
|
|
||||||
|
def by_author(self, author):
|
||||||
|
"""Return comments by author"""
|
||||||
|
return self.filter(author=author)
|
||||||
|
|
||||||
|
|
||||||
|
class Comment(ProjectBaseMixin):
|
||||||
|
"""Comment model."""
|
||||||
|
text = models.TextField(verbose_name=_('Comment text'))
|
||||||
|
mark = models.PositiveIntegerField(blank=True, null=True,
|
||||||
|
default=None,
|
||||||
|
verbose_name=_('Mark'))
|
||||||
|
author = models.ForeignKey('account.User',
|
||||||
|
related_name='comments',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
verbose_name=_('Author'))
|
||||||
|
establishment = models.ForeignKey(Establishment,
|
||||||
|
related_name='comments',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
verbose_name=_('Establishment'))
|
||||||
|
|
||||||
|
objects = CommentQuerySet.as_manager()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta class"""
|
||||||
|
verbose_name = _('Comment')
|
||||||
|
verbose_name_plural = _('Comments')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""String representation"""
|
||||||
|
return str(self.author)
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,57 @@
|
||||||
"""Establishment serializers."""
|
"""Establishment serializers."""
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from establishment import models
|
from establishment import models
|
||||||
from location.serializers import AddressSerializer
|
from location.serializers import AddressSerializer
|
||||||
from main.serializers import MetaDataContentSerializer, AwardSerializer
|
from main.serializers import MetaDataContentSerializer, AwardSerializer, CurrencySerializer
|
||||||
|
from review import models as review_models
|
||||||
from timetable.models import Timetable
|
from timetable.models import Timetable
|
||||||
|
|
||||||
|
|
||||||
|
class ContactPhonesSerializer(serializers.ModelSerializer):
|
||||||
|
"""Contact phone serializer"""
|
||||||
|
class Meta:
|
||||||
|
model = models.ContactPhone
|
||||||
|
fields = [
|
||||||
|
'phone'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ContactEmailsSerializer(serializers.ModelSerializer):
|
||||||
|
"""Contact email serializer"""
|
||||||
|
class Meta:
|
||||||
|
model = models.ContactEmail
|
||||||
|
fields = [
|
||||||
|
'email'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class PlateSerializer(serializers.ModelSerializer):
|
||||||
|
currency = CurrencySerializer(read_only=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = models.Plate
|
||||||
|
fields = [
|
||||||
|
'name_translated',
|
||||||
|
'currency',
|
||||||
|
'price',
|
||||||
|
'is_signature_plate',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class MenuSerializers(serializers.ModelSerializer):
|
||||||
|
plates = PlateSerializer(read_only=True, many=True, source='plate_set')
|
||||||
|
category_translated = serializers.CharField(read_only=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = models.Menu
|
||||||
|
fields = [
|
||||||
|
'id',
|
||||||
|
'category_translated',
|
||||||
|
'plates'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentTypeSerializer(serializers.ModelSerializer):
|
class EstablishmentTypeSerializer(serializers.ModelSerializer):
|
||||||
"""Serializer for EstablishmentType model."""
|
"""Serializer for EstablishmentType model."""
|
||||||
|
|
||||||
|
|
@ -46,6 +92,50 @@ class EstablishmentScheduleSerializer(serializers.ModelSerializer):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ReviewSerializer(serializers.ModelSerializer):
|
||||||
|
"""Serializer for model Review."""
|
||||||
|
text_translated = serializers.CharField(read_only=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta class."""
|
||||||
|
model = review_models.Review
|
||||||
|
fields = (
|
||||||
|
'text_translated',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CommentSerializer(serializers.ModelSerializer):
|
||||||
|
"""Comment serializer"""
|
||||||
|
nickname = serializers.CharField(source='author.username')
|
||||||
|
profile_pic = serializers.ImageField(source='author.image')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Serializer for model Comment"""
|
||||||
|
model = models.Comment
|
||||||
|
fields = (
|
||||||
|
'created',
|
||||||
|
'text',
|
||||||
|
'mark',
|
||||||
|
'nickname',
|
||||||
|
'profile_pic'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class EstablishmentEmployeeSerializer(serializers.ModelSerializer):
|
||||||
|
"""Serializer for actual employees."""
|
||||||
|
|
||||||
|
id = serializers.IntegerField(source='employee.id')
|
||||||
|
name = serializers.CharField(source='employee.name')
|
||||||
|
position_translated = serializers.CharField(source='position.name_translated')
|
||||||
|
awards = AwardSerializer(source='employee.awards', many=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta class."""
|
||||||
|
|
||||||
|
model = models.Employee
|
||||||
|
fields = ('id', 'name', 'position_translated', 'awards')
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentSerializer(serializers.ModelSerializer):
|
class EstablishmentSerializer(serializers.ModelSerializer):
|
||||||
"""Serializer for Establishment model."""
|
"""Serializer for Establishment model."""
|
||||||
|
|
||||||
|
|
@ -59,6 +149,17 @@ class EstablishmentSerializer(serializers.ModelSerializer):
|
||||||
schedule = EstablishmentScheduleSerializer(source='schedule.schedule',
|
schedule = EstablishmentScheduleSerializer(source='schedule.schedule',
|
||||||
many=True,
|
many=True,
|
||||||
allow_null=True)
|
allow_null=True)
|
||||||
|
phones = ContactPhonesSerializer(read_only=True, many=True, )
|
||||||
|
emails = ContactEmailsSerializer(read_only=True, many=True, )
|
||||||
|
reviews = ReviewSerializer(source='reviews.last', allow_null=True)
|
||||||
|
comments = CommentSerializer(many=True, allow_null=True)
|
||||||
|
employees = EstablishmentEmployeeSerializer(source='actual_establishment_employees',
|
||||||
|
many=True)
|
||||||
|
menu = MenuSerializers(source='menu_set', many=True, read_only=True)
|
||||||
|
preview_image = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
best_price_menu = serializers.DecimalField(max_digits=14, decimal_places=2, read_only=True)
|
||||||
|
best_price_carte = serializers.DecimalField(max_digits=14, decimal_places=2, read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
@ -75,8 +176,27 @@ class EstablishmentSerializer(serializers.ModelSerializer):
|
||||||
'type',
|
'type',
|
||||||
'subtypes',
|
'subtypes',
|
||||||
'image',
|
'image',
|
||||||
|
'preview_image',
|
||||||
'address',
|
'address',
|
||||||
'tags',
|
'tags',
|
||||||
'awards',
|
'awards',
|
||||||
'schedule',
|
'schedule',
|
||||||
|
'website',
|
||||||
|
'facebook',
|
||||||
|
'twitter',
|
||||||
|
'lafourchette',
|
||||||
|
'booking',
|
||||||
|
'phones',
|
||||||
|
'emails',
|
||||||
|
'reviews',
|
||||||
|
'comments',
|
||||||
|
'employees',
|
||||||
|
'menu',
|
||||||
|
'best_price_menu',
|
||||||
|
'best_price_carte'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_preview_image(self, obj):
|
||||||
|
"""Get preview image"""
|
||||||
|
return obj.get_full_image_url(request=self.context.get('request'),
|
||||||
|
thumbnail_key='establishment_preview')
|
||||||
|
|
|
||||||
|
|
@ -5,22 +5,32 @@ from utils.views import JWTGenericViewMixin
|
||||||
from establishment import filters
|
from establishment import filters
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentListView(JWTGenericViewMixin, generics.ListAPIView):
|
class EstablishmentMixin:
|
||||||
|
"""Establishment mixin."""
|
||||||
|
|
||||||
|
permission_classes = (permissions.AllowAny,)
|
||||||
|
serializer_class = serializers.EstablishmentSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
"""Overrided method 'get_queryset'."""
|
||||||
|
return models.Establishment.objects.all().prefetch_actual_employees()
|
||||||
|
|
||||||
|
|
||||||
|
class EstablishmentListView(EstablishmentMixin, JWTGenericViewMixin, generics.ListAPIView):
|
||||||
"""Resource for getting a list of establishments."""
|
"""Resource for getting a list of establishments."""
|
||||||
|
|
||||||
permission_classes = (permissions.AllowAny,)
|
|
||||||
serializer_class = serializers.EstablishmentSerializer
|
|
||||||
queryset = models.Establishment.objects.all()
|
|
||||||
filter_class = filters.EstablishmentFilter
|
filter_class = filters.EstablishmentFilter
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
"""Overrided method 'get_queryset'."""
|
||||||
|
return models.Establishment.objects.all()\
|
||||||
|
.prefetch_actual_employees()\
|
||||||
|
.by_country_code(code=self.request.country_code)
|
||||||
|
|
||||||
class EstablishmentRetrieveView(JWTGenericViewMixin, generics.RetrieveAPIView):
|
|
||||||
|
class EstablishmentRetrieveView(EstablishmentMixin, JWTGenericViewMixin, generics.RetrieveAPIView):
|
||||||
"""Resource for getting a establishment."""
|
"""Resource for getting a establishment."""
|
||||||
|
|
||||||
permission_classes = (permissions.AllowAny,)
|
|
||||||
serializer_class = serializers.EstablishmentSerializer
|
|
||||||
queryset = models.Establishment.objects.all()
|
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentTypeListView(JWTGenericViewMixin, generics.ListAPIView):
|
class EstablishmentTypeListView(JWTGenericViewMixin, generics.ListAPIView):
|
||||||
"""Resource for getting a list of establishment types."""
|
"""Resource for getting a list of establishment types."""
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,6 @@ class Migration(migrations.Migration):
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='country',
|
model_name='country',
|
||||||
name='name',
|
name='name',
|
||||||
field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=None, help_text='{"en":"some text"}', null=True, verbose_name='Text'),
|
field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='Text'),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
19
apps/location/migrations/0009_auto_20190901_0831.py
Normal file
19
apps/location/migrations/0009_auto_20190901_0831.py
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 08:31
|
||||||
|
|
||||||
|
import django.contrib.postgres.fields.jsonb
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('location', '0008_auto_20190827_1302'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='country',
|
||||||
|
name='name',
|
||||||
|
field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='Name'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -17,7 +17,7 @@ class Country(SVGImageMixin, ProjectBaseMixin):
|
||||||
"""Country model."""
|
"""Country model."""
|
||||||
|
|
||||||
name = JSONField(null=True, blank=True, default=None,
|
name = JSONField(null=True, blank=True, default=None,
|
||||||
verbose_name=_('Name'), help_text='{"en":"some text"}')
|
verbose_name=_('Name'), help_text='{"en-GB":"some text"}')
|
||||||
code = models.CharField(max_length=255, unique=True, verbose_name=_('Code'))
|
code = models.CharField(max_length=255, unique=True, verbose_name=_('Code'))
|
||||||
low_price = models.IntegerField(default=25, verbose_name=_('Low price'))
|
low_price = models.IntegerField(default=25, verbose_name=_('Low price'))
|
||||||
high_price = models.IntegerField(default=50, verbose_name=_('High price'))
|
high_price = models.IntegerField(default=50, verbose_name=_('High price'))
|
||||||
|
|
|
||||||
|
|
@ -39,3 +39,10 @@ class MetaDataCategoryAdmin(admin.ModelAdmin):
|
||||||
@admin.register(models.MetaDataContent)
|
@admin.register(models.MetaDataContent)
|
||||||
class MetaDataContentAdmin(admin.ModelAdmin):
|
class MetaDataContentAdmin(admin.ModelAdmin):
|
||||||
"""MetaDataContent admin"""
|
"""MetaDataContent admin"""
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(models.Currency)
|
||||||
|
class CurrencContentAdmin(admin.ModelAdmin):
|
||||||
|
"""CurrencContent admin"""
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
35
apps/main/migrations/0013_auto_20190901_1032.py
Normal file
35
apps/main/migrations/0013_auto_20190901_1032.py
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 10:32
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import utils.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('main', '0012_auto_20190829_1155'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Currency',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=50, verbose_name='name')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'currency',
|
||||||
|
'verbose_name_plural': 'currencies',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='award',
|
||||||
|
name='title',
|
||||||
|
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='title'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='metadata',
|
||||||
|
name='label',
|
||||||
|
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='label'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -190,7 +190,7 @@ class Award(TraslatedFieldsMixin, models.Model):
|
||||||
award_type = models.ForeignKey('main.AwardType', on_delete=models.CASCADE)
|
award_type = models.ForeignKey('main.AwardType', on_delete=models.CASCADE)
|
||||||
title = TJSONField(
|
title = TJSONField(
|
||||||
_('title'), null=True, blank=True,
|
_('title'), null=True, blank=True,
|
||||||
default=None, help_text='{"en":"some text"}')
|
default=None, help_text='{"en-GB":"some text"}')
|
||||||
vintage_year = models.CharField(_('vintage year'), max_length=255, default='')
|
vintage_year = models.CharField(_('vintage year'), max_length=255, default='')
|
||||||
|
|
||||||
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
|
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
|
||||||
|
|
@ -228,7 +228,7 @@ class MetaData(TraslatedFieldsMixin, models.Model):
|
||||||
"""MetaData model."""
|
"""MetaData model."""
|
||||||
label = TJSONField(
|
label = TJSONField(
|
||||||
_('label'), null=True, blank=True,
|
_('label'), null=True, blank=True,
|
||||||
default=None, help_text='{"en":"some text"}')
|
default=None, help_text='{"en-GB":"some text"}')
|
||||||
category = models.ForeignKey(
|
category = models.ForeignKey(
|
||||||
MetaDataCategory, verbose_name=_('category'), on_delete=models.CASCADE)
|
MetaDataCategory, verbose_name=_('category'), on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
|
@ -250,3 +250,15 @@ class MetaDataContent(models.Model):
|
||||||
object_id = models.PositiveIntegerField()
|
object_id = models.PositiveIntegerField()
|
||||||
content_object = generic.GenericForeignKey('content_type', 'object_id')
|
content_object = generic.GenericForeignKey('content_type', 'object_id')
|
||||||
metadata = models.ForeignKey(MetaData, on_delete=models.CASCADE)
|
metadata = models.ForeignKey(MetaData, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
|
||||||
|
class Currency(models.Model):
|
||||||
|
"""Currency model."""
|
||||||
|
name = models.CharField(_('name'), max_length=50)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _('currency')
|
||||||
|
verbose_name_plural = _('currencies')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'{self.name}'
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ class SiteSettingsSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class AwardSerializer(serializers.ModelSerializer):
|
class AwardSerializer(serializers.ModelSerializer):
|
||||||
"""Award serializer."""
|
"""Award serializer."""
|
||||||
|
|
||||||
title_translated = serializers.CharField(read_only=True, allow_null=True)
|
title_translated = serializers.CharField(read_only=True, allow_null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
@ -95,4 +96,14 @@ class MetaDataContentSerializer(serializers.ModelSerializer):
|
||||||
fields = [
|
fields = [
|
||||||
'id',
|
'id',
|
||||||
'label_translated',
|
'label_translated',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class CurrencySerializer(serializers.ModelSerializer):
|
||||||
|
"""Currency serializer"""
|
||||||
|
class Meta:
|
||||||
|
model = models.Currency
|
||||||
|
fields = [
|
||||||
|
'id',
|
||||||
|
'name'
|
||||||
]
|
]
|
||||||
|
|
@ -22,7 +22,7 @@ class NewsListFilterSet(django_filters.FilterSet):
|
||||||
"""Crappy search by title according to locale"""
|
"""Crappy search by title according to locale"""
|
||||||
if value:
|
if value:
|
||||||
locale = self.request.locale
|
locale = self.request.locale
|
||||||
filters = {f'{name}__{locale}': value}
|
filters = {f'{name}__{locale}__icontains': value}
|
||||||
return queryset.filter(**filters)
|
return queryset.filter(**filters)
|
||||||
else:
|
else:
|
||||||
return queryset
|
return queryset
|
||||||
|
|
|
||||||
29
apps/news/migrations/0009_auto_20190901_1032.py
Normal file
29
apps/news/migrations/0009_auto_20190901_1032.py
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 10:32
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
import utils.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('news', '0008_auto_20190828_1522'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='news',
|
||||||
|
name='description',
|
||||||
|
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='description'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='news',
|
||||||
|
name='subtitle',
|
||||||
|
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='subtitle'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='news',
|
||||||
|
name='title',
|
||||||
|
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='title'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -43,14 +43,14 @@ class News(BaseAttributes, TraslatedFieldsMixin):
|
||||||
|
|
||||||
title = TJSONField(
|
title = TJSONField(
|
||||||
_('title'), null=True, blank=True,
|
_('title'), null=True, blank=True,
|
||||||
default=None, help_text='{"en":"some text"}')
|
default=None, help_text='{"en-GB":"some text"}')
|
||||||
subtitle = TJSONField(
|
subtitle = TJSONField(
|
||||||
_('subtitle'), null=True, blank=True,
|
_('subtitle'), null=True, blank=True,
|
||||||
default=None, help_text='{"en":"some text"}'
|
default=None, help_text='{"en-GB":"some text"}'
|
||||||
)
|
)
|
||||||
description = TJSONField(
|
description = TJSONField(
|
||||||
_('description'), null=True, blank=True,
|
_('description'), null=True, blank=True,
|
||||||
default=None, help_text='{"en":"some text"}'
|
default=None, help_text='{"en-GB":"some text"}'
|
||||||
)
|
)
|
||||||
start = models.DateTimeField(_('start'))
|
start = models.DateTimeField(_('start'))
|
||||||
end = models.DateTimeField(_('end'))
|
end = models.DateTimeField(_('end'))
|
||||||
|
|
|
||||||
0
apps/review/__init__.py
Normal file
0
apps/review/__init__.py
Normal file
3
apps/review/admin.py
Normal file
3
apps/review/admin.py
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# @admin.register(models.Review)
|
||||||
|
# class ReviewAdminModel(admin.ModelAdmin):
|
||||||
|
# """Admin model for model Review."""
|
||||||
7
apps/review/apps.py
Normal file
7
apps/review/apps.py
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
|
class ReviewConfig(AppConfig):
|
||||||
|
name = 'review'
|
||||||
|
verbose_name = _('reviews')
|
||||||
43
apps/review/migrations/0001_initial.py
Normal file
43
apps/review/migrations/0001_initial.py
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 09:32
|
||||||
|
|
||||||
|
import django.core.validators
|
||||||
|
import django.utils.timezone
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contenttypes', '0002_remove_content_type_name'),
|
||||||
|
('translation', '0002_siteinterfacedictionary'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Review',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('created', models.DateTimeField(default=django.utils.timezone.now, editable=False, verbose_name='Date created')),
|
||||||
|
('modified', models.DateTimeField(auto_now=True, verbose_name='Date updated')),
|
||||||
|
('object_id', models.PositiveIntegerField()),
|
||||||
|
('text', models.TextField(verbose_name='Text')),
|
||||||
|
('status', models.PositiveSmallIntegerField(choices=[(0, 'To investigate'), (1, 'To review'), (2, 'Ready')], default=0)),
|
||||||
|
('published_at', models.DateTimeField(blank=True, default=None, help_text='Review published datetime', null=True, verbose_name='Publish datetime')),
|
||||||
|
('vintage', models.IntegerField(validators=[django.core.validators.MinValueValidator(1900), django.core.validators.MaxValueValidator(2100)], verbose_name='Year of review')),
|
||||||
|
('child', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='review.Review', verbose_name='Child review')),
|
||||||
|
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')),
|
||||||
|
('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='review_records_created', to=settings.AUTH_USER_MODEL, verbose_name='created by')),
|
||||||
|
('language', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviews', to='translation.Language', verbose_name='Review language')),
|
||||||
|
('modified_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='review_records_modified', to=settings.AUTH_USER_MODEL, verbose_name='modified by')),
|
||||||
|
('reviewer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviews', to=settings.AUTH_USER_MODEL, verbose_name='Reviewer')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Review',
|
||||||
|
'verbose_name_plural': 'Reviews',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
17
apps/review/migrations/0002_remove_review_text.py
Normal file
17
apps/review/migrations/0002_remove_review_text.py
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 11:47
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('review', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='review',
|
||||||
|
name='text',
|
||||||
|
),
|
||||||
|
]
|
||||||
20
apps/review/migrations/0003_review_text.py
Normal file
20
apps/review/migrations/0003_review_text.py
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 11:53
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
import utils.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('review', '0002_remove_review_text'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='review',
|
||||||
|
name='text',
|
||||||
|
field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"Text review"}', null=True, verbose_name='text'),
|
||||||
|
),
|
||||||
|
]
|
||||||
0
apps/review/migrations/__init__.py
Normal file
0
apps/review/migrations/__init__.py
Normal file
64
apps/review/models.py
Normal file
64
apps/review/models.py
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
from django.contrib.contenttypes import fields as generic
|
||||||
|
from django.core.validators import MinValueValidator, MaxValueValidator
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from utils.models import BaseAttributes, TraslatedFieldsMixin
|
||||||
|
from utils.models import TJSONField
|
||||||
|
|
||||||
|
|
||||||
|
class ReviewQuerySet(models.QuerySet):
|
||||||
|
"""QuerySets for model Review"""
|
||||||
|
|
||||||
|
def by_reviewer(self, user):
|
||||||
|
"""Return reviews by user"""
|
||||||
|
return self.filter(reviewer=user)
|
||||||
|
|
||||||
|
def by_vintage(self, year: int):
|
||||||
|
"""Return reviews by year"""
|
||||||
|
return self.filter(vintage=year)
|
||||||
|
|
||||||
|
|
||||||
|
class Review(BaseAttributes, TraslatedFieldsMixin):
|
||||||
|
"""Review model"""
|
||||||
|
TO_INVESTIGATE = 0
|
||||||
|
TO_REVIEW = 1
|
||||||
|
READY = 2
|
||||||
|
REVIEW_STATUSES = (
|
||||||
|
(TO_INVESTIGATE, _('To investigate')),
|
||||||
|
(TO_REVIEW, _('To review')),
|
||||||
|
(READY, _('Ready')),
|
||||||
|
)
|
||||||
|
|
||||||
|
reviewer = models.ForeignKey('account.User',
|
||||||
|
related_name='reviews',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
verbose_name=_('Reviewer'))
|
||||||
|
text = TJSONField(
|
||||||
|
_('text'), null=True, blank=True,
|
||||||
|
default=None, help_text='{"en-GB":"Text review"}')
|
||||||
|
content_type = models.ForeignKey(generic.ContentType, on_delete=models.CASCADE)
|
||||||
|
object_id = models.PositiveIntegerField()
|
||||||
|
content_object = generic.GenericForeignKey('content_type', 'object_id')
|
||||||
|
language = models.ForeignKey('translation.Language',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name='reviews',
|
||||||
|
verbose_name=_('Review language'))
|
||||||
|
status = models.PositiveSmallIntegerField(choices=REVIEW_STATUSES, default=TO_INVESTIGATE)
|
||||||
|
child = models.ForeignKey('self',
|
||||||
|
blank=True, default=None, null=True,
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
verbose_name=_('Child review'))
|
||||||
|
published_at = models.DateTimeField(verbose_name=_('Publish datetime'),
|
||||||
|
blank=True, default=None, null=True,
|
||||||
|
help_text=_('Review published datetime'))
|
||||||
|
vintage = models.IntegerField(verbose_name=_('Year of review'),
|
||||||
|
validators=[MinValueValidator(1900),
|
||||||
|
MaxValueValidator(2100)])
|
||||||
|
|
||||||
|
objects = ReviewQuerySet.as_manager()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta class."""
|
||||||
|
verbose_name = _('Review')
|
||||||
|
verbose_name_plural = _('Reviews')
|
||||||
0
apps/review/serializers/__init__.py
Normal file
0
apps/review/serializers/__init__.py
Normal file
0
apps/review/serializers/common.py
Normal file
0
apps/review/serializers/common.py
Normal file
0
apps/review/serializers/mobile.py
Normal file
0
apps/review/serializers/mobile.py
Normal file
0
apps/review/serializers/web.py
Normal file
0
apps/review/serializers/web.py
Normal file
3
apps/review/tests.py
Normal file
3
apps/review/tests.py
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
||||||
0
apps/review/urls/__init__.py
Normal file
0
apps/review/urls/__init__.py
Normal file
0
apps/review/urls/common.py
Normal file
0
apps/review/urls/common.py
Normal file
0
apps/review/urls/mobile.py
Normal file
0
apps/review/urls/mobile.py
Normal file
0
apps/review/urls/web.py
Normal file
0
apps/review/urls/web.py
Normal file
0
apps/review/views/__init__.py
Normal file
0
apps/review/views/__init__.py
Normal file
0
apps/review/views/common.py
Normal file
0
apps/review/views/common.py
Normal file
0
apps/review/views/mobile.py
Normal file
0
apps/review/views/mobile.py
Normal file
0
apps/review/views/web.py
Normal file
0
apps/review/views/web.py
Normal file
19
apps/translation/migrations/0003_auto_20190901_1032.py
Normal file
19
apps/translation/migrations/0003_auto_20190901_1032.py
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-01 10:32
|
||||||
|
|
||||||
|
import django.contrib.postgres.fields.jsonb
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('translation', '0002_siteinterfacedictionary'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='siteinterfacedictionary',
|
||||||
|
name='text',
|
||||||
|
field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='Text'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -49,7 +49,7 @@ class SiteInterfaceDictionary(ProjectBaseMixin):
|
||||||
verbose_name=_('Page'))
|
verbose_name=_('Page'))
|
||||||
keywords = models.CharField(max_length=255, verbose_name='Keywords')
|
keywords = models.CharField(max_length=255, verbose_name='Keywords')
|
||||||
text = JSONField(_('Text'), null=True, blank=True,
|
text = JSONField(_('Text'), null=True, blank=True,
|
||||||
default=None, help_text='{"en":"some text"}')
|
default=None, help_text='{"en-GB":"some text"}')
|
||||||
|
|
||||||
objects = SiteInterfaceDictionaryManager()
|
objects = SiteInterfaceDictionaryManager()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,9 +74,6 @@ class OAuthProjectMixin:
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
||||||
|
|
||||||
basemixin_fields = ['created', 'modified']
|
|
||||||
|
|
||||||
|
|
||||||
class BaseAttributes(ProjectBaseMixin):
|
class BaseAttributes(ProjectBaseMixin):
|
||||||
created_by = models.ForeignKey(
|
created_by = models.ForeignKey(
|
||||||
'account.User', on_delete=models.SET_NULL, verbose_name=_('created by'),
|
'account.User', on_delete=models.SET_NULL, verbose_name=_('created by'),
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ PROJECT_APPS = [
|
||||||
'translation.apps.TranslationConfig',
|
'translation.apps.TranslationConfig',
|
||||||
'configuration.apps.ConfigurationConfig',
|
'configuration.apps.ConfigurationConfig',
|
||||||
'timetable.apps.TimetableConfig',
|
'timetable.apps.TimetableConfig',
|
||||||
|
'review.apps.ReviewConfig',
|
||||||
]
|
]
|
||||||
|
|
||||||
EXTERNAL_APPS = [
|
EXTERNAL_APPS = [
|
||||||
|
|
@ -82,6 +83,7 @@ EXTERNAL_APPS = [
|
||||||
'django_extensions',
|
'django_extensions',
|
||||||
'rest_framework_simplejwt.token_blacklist',
|
'rest_framework_simplejwt.token_blacklist',
|
||||||
'solo',
|
'solo',
|
||||||
|
'phonenumber_field',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -321,6 +323,7 @@ THUMBNAIL_ALIASES = {
|
||||||
'large': {'size': (1500, 0), },
|
'large': {'size': (1500, 0), },
|
||||||
'default': {'size': (300, 200), 'crop': True},
|
'default': {'size': (300, 200), 'crop': True},
|
||||||
'gallery': {'size': (240, 160), 'crop': True},
|
'gallery': {'size': (240, 160), 'crop': True},
|
||||||
|
'establishment_preview': {'size': (300, 280), 'crop': True},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ djangorestframework-xml
|
||||||
celery
|
celery
|
||||||
amqp>=2.4.0
|
amqp>=2.4.0
|
||||||
geoip2==2.9.0
|
geoip2==2.9.0
|
||||||
|
django-phonenumber-field[phonenumbers]==2.1.0
|
||||||
|
|
||||||
# auth socials
|
# auth socials
|
||||||
djangorestframework-oauth
|
djangorestframework-oauth
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user