production settings + menu tree implementation

This commit is contained in:
Bossanyi Tibor 2020-07-18 17:29:32 +02:00
parent c9f22e0f96
commit 35a3a9b0f9
7 changed files with 255 additions and 26 deletions

View File

View File

@ -4,6 +4,8 @@ from django.utils.translation import ugettext_lazy as _
from .models import ExerciseType from .models import ExerciseType
from .models import ExerciseTypeImage from .models import ExerciseTypeImage
from .models import ExerciseTypeTranslation from .models import ExerciseTypeTranslation
from .models import ExerciseTreeTranslation
from .models import ExerciseTree
class ImageInline(admin.StackedInline): class ImageInline(admin.StackedInline):
@ -28,7 +30,7 @@ class TranslationInline(admin.TabularInline):
class ExerciseTypeAdmin(admin.ModelAdmin): class ExerciseTypeAdmin(admin.ModelAdmin):
list_display = ('exercise_type_id', 'name_colored', 'active') list_display = ('name_colored', 'active')
search_fields = ['name'] search_fields = ['name']
def name_colored(self, obj): def name_colored(self, obj):
@ -48,4 +50,42 @@ class ExerciseTypeAdmin(admin.ModelAdmin):
] ]
class TranslationTreeInline(admin.TabularInline):
model = ExerciseTreeTranslation
fields = ('language_code', 'name',)
extra = 0
class ExerciseTreeAdmin(admin.ModelAdmin):
list_display = ('name_colored', 'active')
search_fields = ['name']
fields = ["name", "parent_id", "image_url", "active", "get_image_preview"]
readonly_fields = ("get_image_preview",)
def get_image_preview(self, obj):
image_url = '/media/' + str(obj.image_url)
if obj.pk:
return format_html('<img src="{url}" title="{url}" width="30%" height="30%"/> ' \
.format(url=image_url))
get_image_preview.short_description = _("Image Preview")
def name_colored(self, obj):
if obj.active:
color_code = '7bc863'
else:
color_code = 'C20000'
html = '<span style="color: #{};">{}</span>˓→'.format(color_code, obj.name)
return format_html(html)
name_colored.admin_order_field = 'name'
name_colored.short_description = 'name'
inlines = [
TranslationTreeInline
]
admin.site.register(ExerciseType, ExerciseTypeAdmin) admin.site.register(ExerciseType, ExerciseTypeAdmin)
admin.site.register(ExerciseTree, ExerciseTreeAdmin)

View File

@ -8,7 +8,7 @@ class ExerciseType(models.Model):
SECOND = 'second' SECOND = 'second'
MINUTE = 'minute' MINUTE = 'minute'
METER = 'meter' METER = 'meter'
CM= 'centimeter' CM = 'centimeter'
PERCENT = 'percent' PERCENT = 'percent'
CALORIES = 'calories' CALORIES = 'calories'
KG = 'kilogram' KG = 'kilogram'
@ -19,7 +19,8 @@ class ExerciseType(models.Model):
'English here') 'English here')
unit = models.CharField(choices=UnitTypes.choices, default=UnitTypes.REPEAT, max_length=50, blank=True, null=True) unit = models.CharField(choices=UnitTypes.choices, default=UnitTypes.REPEAT, max_length=50, blank=True, null=True)
unit_quantity = models.BooleanField(default=0, blank=True, null=True) unit_quantity = models.BooleanField(default=0, blank=True, null=True)
unit_quantity_unit = models.CharField(choices=UnitTypes.choices, default=UnitTypes.KG, max_length=50, blank=True, null=True) unit_quantity_unit = models.CharField(choices=UnitTypes.choices, default=UnitTypes.KG, max_length=50, blank=True,
null=True)
active = models.BooleanField(default=0, blank=True, null=True) active = models.BooleanField(default=0, blank=True, null=True)
class Meta: class Meta:
@ -51,20 +52,13 @@ class ExerciseTypeImage(models.Model):
def __str__(self): def __str__(self):
return self.name return self.name
'''
def image_tag(self): class LanguageTypes(models.TextChoices):
from django.utils.html import escape EN = "en"
return u'<img src="%s" />' % escape(self.obj.url) HU = "hu"
image_tag.short_description = 'Image'
image_tag.allow_tags = True
'''
class ExerciseTypeTranslation(models.Model): class ExerciseTypeTranslation(models.Model):
class LanguageTypes(models.TextChoices):
EN = "en"
HU = "hu"
translation_id = models.AutoField(primary_key=True) translation_id = models.AutoField(primary_key=True)
exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE) exercise_type = models.ForeignKey(ExerciseType, on_delete=models.CASCADE)
language_code = models.CharField(max_length=2, choices=LanguageTypes.choices, default=LanguageTypes.HU) language_code = models.CharField(max_length=2, choices=LanguageTypes.choices, default=LanguageTypes.HU)
@ -78,3 +72,34 @@ class ExerciseTypeTranslation(models.Model):
def __str__(self): def __str__(self):
return self.name return self.name
class ExerciseTree(models.Model):
item_id = models.AutoField(primary_key=True)
parent_id = models.IntegerField(help_text='This is the parent menu ID. 0 if it is on the top of the tree')
name = models.CharField(max_length=100, help_text='The name should be in English here')
image_url = models.ImageField(upload_to='images/', help_text='The menu image size is 1366x768')
active = models.BooleanField(default=0, blank=True, null=True)
class Meta:
db_table = 'exercise_tree'
verbose_name = _("Exercise Tree")
verbose_name_plural = _("Exercise Tree Items")
def __str__(self):
return self.name
class ExerciseTreeTranslation(models.Model):
translation_id = models.AutoField(primary_key=True)
tree = models.ForeignKey(ExerciseTree, on_delete=models.CASCADE)
language_code = models.CharField(max_length=2, choices=LanguageTypes.choices, default=LanguageTypes.HU)
name = models.CharField(max_length=100)
class Meta:
db_table = 'exercise_tree_translation'
verbose_name = _("Translation")
verbose_name_plural = _("Translations")
def __str__(self):
return self.name

View File

@ -0,0 +1 @@
from .dev import *

View File

@ -1,5 +1,5 @@
""" """
Django settings for aitrainer_backoffice project. Django settings for aitrainer_backoffice project. (development)
Generated by 'django-admin startproject' using Django 3.0.8. Generated by 'django-admin startproject' using Django 3.0.8.
@ -15,18 +15,16 @@ import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ # See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret! # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'fic(oo70m2itz&6-=!)j)$g+p8(s#aud7u7tpaqxd&2562grb@' SECRET_KEY = os.environ['DJANGO_KEY']
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = True
ALLOWED_HOSTS = [] ALLOWED_HOSTS = ['localhost']
# Application definition # Application definition
@ -70,7 +68,6 @@ TEMPLATES = [
WSGI_APPLICATION = 'aitrainer_backoffice.wsgi.application' WSGI_APPLICATION = 'aitrainer_backoffice.wsgi.application'
# Database # Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases # https://docs.djangoproject.com/en/3.0/ref/settings/#databases
@ -79,13 +76,12 @@ DATABASES = {
'ENGINE': 'django.db.backends.mysql', 'ENGINE': 'django.db.backends.mysql',
'NAME': 'aitrainer2', 'NAME': 'aitrainer2',
'USER': 'aitrainer', 'USER': 'aitrainer',
'PASSWORD':'andio2009', 'PASSWORD': 'andio2009',
'HOST': '127.0.0.1', 'HOST': '127.0.0.1',
'PORT':3306 'PORT': 3306
} }
} }
# Password validation # Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators # https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
@ -104,7 +100,6 @@ AUTH_PASSWORD_VALIDATORS = [
}, },
] ]
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/ # https://docs.djangoproject.com/en/3.0/topics/i18n/
@ -118,7 +113,6 @@ USE_L10N = True
USE_TZ = True USE_TZ = True
# Static files (CSS, JavaScript, Images) # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/ # https://docs.djangoproject.com/en/3.0/howto/static-files/

View File

@ -0,0 +1,168 @@
"""
Django settings for aitrainer_backoffice project.
Generated by 'django-admin startproject' using Django 3.0.8.
For more information on this file, see
https://docs.djangoproject.com/en/3.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.0/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ['DJANGO_KEY']
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ['localhost', 'andio.eu', 'aitrainer.*']
# Application definition
INSTALLED_APPS = [
'aitrainer_backoffice.apps.BackofficeConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'aitrainer_backoffice.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'aitrainer_backoffice.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'aitrainer2',
'USER': 'aitrainer',
'PASSWORD': 'andio2009',
'HOST': '127.0.0.1',
'PORT': 3306
}
}
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGE_CODE = 'hu-HU'
TIME_ZONE = 'Europe/Budapest'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'filters': ['require_debug_true'],
},
},
'loggers': {
'mylogger': {
'handlers': {
'file': {
'level': 'ERROR',
'class': 'logging.FileHandler',
'filename': '/var/log/django_error.log',
},
},
'level': os.getenv('DJANGO_LOG_LEVEL', 'ERROR'),
'propagate': True,
},
},
}
# deployment settings
SECURE_SSL_REDIRECT = False
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
'TIMEOUT': 300,
'OPTIONS': {
'MAX_ENTRIES': 50000
}
}
}

View File

@ -11,6 +11,7 @@ import os
from django.core.wsgi import get_wsgi_application from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'aitrainer_backoffice.settings') os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'aitrainer_backoffice.settings.prod')
application = get_wsgi_application() application = get_wsgi_application()