add: add common models, translations and register on admin panel
This commit is contained in:
@@ -13,6 +13,7 @@ ALLOWED_HOSTS = env.list('ALLOWED_HOSTS')
|
|||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
'jazzmin',
|
'jazzmin',
|
||||||
|
'modeltranslation',
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
'django.contrib.contenttypes',
|
'django.contrib.contenttypes',
|
||||||
@@ -118,3 +119,11 @@ EMAIL_PORT = env.str('EMAIL_PORT')
|
|||||||
EMAIL_USE_TLS = env.str('EMAIL_USE_TLS')
|
EMAIL_USE_TLS = env.str('EMAIL_USE_TLS')
|
||||||
|
|
||||||
from config.conf import *
|
from config.conf import *
|
||||||
|
|
||||||
|
MODELTRANSLATION_DEFAULT_LANGUAGE = 'uz'
|
||||||
|
LANGUAGES = (
|
||||||
|
('uz', 'Uzbek'),
|
||||||
|
('en', 'English'),
|
||||||
|
('ru', 'Russian'),
|
||||||
|
)
|
||||||
|
MODELTRANSLATION_LANGUAGES = ('uz', 'en', 'ru')
|
||||||
|
|||||||
@@ -1,3 +1,70 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
# Register your models here.
|
from django.http import HttpResponseRedirect
|
||||||
|
from django.urls import reverse
|
||||||
|
from modeltranslation.admin import TranslationAdmin, TranslationTabularInline
|
||||||
|
|
||||||
|
from core.apps.common import models
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(models.Banner)
|
||||||
|
class BannerAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ['banner']
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(models.SiteConfig)
|
||||||
|
class SiteConfigAdmin(admin.ModelAdmin):
|
||||||
|
def has_delete_permission(self, request, obj=...):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def changelist_view(self, request, extra_context=None):
|
||||||
|
config, create = models.SiteConfig.objects.get_or_create(
|
||||||
|
defaults=dict(
|
||||||
|
telegram='https://t.me/telegram',
|
||||||
|
facebook='https://facebook.com',
|
||||||
|
instagram='https://instagram.com',
|
||||||
|
youtube='https://youtube.com',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
url = reverse('admin:common_siteconfig_change', args=[config.id])
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
|
|
||||||
|
class AboutUsImageInline(admin.TabularInline):
|
||||||
|
model = models.AboutUsImage
|
||||||
|
extra = 0
|
||||||
|
verbose_name = 'rasm'
|
||||||
|
verbose_name_plural = 'rasmlar'
|
||||||
|
|
||||||
|
|
||||||
|
class AboutUsFeatureInline(TranslationTabularInline):
|
||||||
|
model = models.AboutUsFeature
|
||||||
|
extra = 0
|
||||||
|
verbose_name = 'xususiyat'
|
||||||
|
verbose_name_plural = 'xususiyatlar'
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(models.AboutUs)
|
||||||
|
class AboutUsAdmin(TranslationAdmin):
|
||||||
|
list_display = ['title', 'description']
|
||||||
|
inlines = [AboutUsImageInline, AboutUsFeatureInline]
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(models.Service)
|
||||||
|
class ServiceAdmin(TranslationAdmin):
|
||||||
|
list_display = ['title', 'text', 'icon', 'image']
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(models.ContactUs)
|
||||||
|
class ContactUsAdmin(admin.ModelAdmin):
|
||||||
|
list_display = [
|
||||||
|
'email', 'phone', 'is_contacted'
|
||||||
|
]
|
||||||
|
|
||||||
|
def has_add_permission(self, request):
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(models.News)
|
||||||
|
class NewsAdmin(TranslationAdmin):
|
||||||
|
list_display = ['title', 'text', 'image']
|
||||||
155
core/apps/common/migrations/0001_initial.py
Normal file
155
core/apps/common/migrations/0001_initial.py
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
# Generated by Django 5.2 on 2025-08-26 12:25
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
import uuid
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='AboutUs',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateField(auto_now=True)),
|
||||||
|
('title', models.CharField(max_length=200)),
|
||||||
|
('title_uz', models.CharField(max_length=200, null=True)),
|
||||||
|
('title_en', models.CharField(max_length=200, null=True)),
|
||||||
|
('title_ru', models.CharField(max_length=200, null=True)),
|
||||||
|
('description', models.TextField()),
|
||||||
|
('description_uz', models.TextField(null=True)),
|
||||||
|
('description_en', models.TextField(null=True)),
|
||||||
|
('description_ru', models.TextField(null=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'biz haqimizda',
|
||||||
|
'verbose_name_plural': 'biz haqimizda',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Banner',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateField(auto_now=True)),
|
||||||
|
('banner', models.ImageField(upload_to='banner/images/')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'banner',
|
||||||
|
'verbose_name_plural': 'bannerlar',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='News',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateField(auto_now=True)),
|
||||||
|
('image', models.ImageField(unique='news/images/', upload_to='')),
|
||||||
|
('title', models.CharField(max_length=300)),
|
||||||
|
('title_uz', models.CharField(max_length=300, null=True)),
|
||||||
|
('title_en', models.CharField(max_length=300, null=True)),
|
||||||
|
('title_ru', models.CharField(max_length=300, null=True)),
|
||||||
|
('text', models.TextField()),
|
||||||
|
('text_uz', models.TextField(null=True)),
|
||||||
|
('text_en', models.TextField(null=True)),
|
||||||
|
('text_ru', models.TextField(null=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'yangilik',
|
||||||
|
'verbose_name_plural': 'yangiliklar',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Service',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateField(auto_now=True)),
|
||||||
|
('title', models.CharField(max_length=200)),
|
||||||
|
('title_uz', models.CharField(max_length=200, null=True)),
|
||||||
|
('title_en', models.CharField(max_length=200, null=True)),
|
||||||
|
('title_ru', models.CharField(max_length=200, null=True)),
|
||||||
|
('text', models.TextField()),
|
||||||
|
('text_uz', models.TextField(null=True)),
|
||||||
|
('text_en', models.TextField(null=True)),
|
||||||
|
('text_ru', models.TextField(null=True)),
|
||||||
|
('icon', models.ImageField(upload_to='service/icons/')),
|
||||||
|
('image', models.ImageField(upload_to='service/images/')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='SiteConfir',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateField(auto_now=True)),
|
||||||
|
('telegram', models.URLField()),
|
||||||
|
('facebook', models.URLField()),
|
||||||
|
('youtube', models.URLField()),
|
||||||
|
('instagram', models.URLField()),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'sayt sozlamalari',
|
||||||
|
'verbose_name_plural': 'sayt sozlamalari',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='AboutUsFeature',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateField(auto_now=True)),
|
||||||
|
('text', models.CharField(max_length=200)),
|
||||||
|
('text_uz', models.CharField(max_length=200, null=True)),
|
||||||
|
('text_en', models.CharField(max_length=200, null=True)),
|
||||||
|
('text_ru', models.CharField(max_length=200, null=True)),
|
||||||
|
('about_us', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='features', to='common.aboutus')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='AboutUsImage',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateField(auto_now=True)),
|
||||||
|
('image', models.ImageField(upload_to='about_us/images/')),
|
||||||
|
('about_us', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='images', to='common.aboutus')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='ContactUs',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateField(auto_now=True)),
|
||||||
|
('first_name', models.CharField(max_length=200)),
|
||||||
|
('last_name', models.CharField(max_length=200)),
|
||||||
|
('phone', models.CharField(max_length=15)),
|
||||||
|
('email', models.EmailField(max_length=254)),
|
||||||
|
('message', models.TextField()),
|
||||||
|
('is_contacted', models.BooleanField(default=False)),
|
||||||
|
('service', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contract_us', to='common.service')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'ariza',
|
||||||
|
'verbose_name_plural': 'arizalar',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Generated by Django 5.2 on 2025-08-26 12:26
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('common', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RenameModel(
|
||||||
|
old_name='SiteConfir',
|
||||||
|
new_name='SiteConfig',
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -9,3 +9,117 @@ class BaseModel(models.Model):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
|
||||||
|
class Banner(BaseModel):
|
||||||
|
banner = models.ImageField(upload_to='banner/images/')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.banner.name
|
||||||
|
|
||||||
|
def delete(self, *args, **kwargs):
|
||||||
|
if self.banner:
|
||||||
|
self.banner.delete(save=False)
|
||||||
|
super().delete(*args, **kwargs)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = 'banner'
|
||||||
|
verbose_name_plural = 'bannerlar'
|
||||||
|
|
||||||
|
|
||||||
|
class AboutUs(BaseModel):
|
||||||
|
title = models.CharField(max_length=200)
|
||||||
|
description = models.TextField()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.title
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = 'biz haqimizda'
|
||||||
|
verbose_name_plural = 'biz haqimizda'
|
||||||
|
|
||||||
|
|
||||||
|
class AboutUsImage(BaseModel):
|
||||||
|
image = models.ImageField(upload_to='about_us/images/')
|
||||||
|
about_us = models.ForeignKey(AboutUs, on_delete=models.CASCADE, related_name='images')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'{self.about_us} image {self.image.name}'
|
||||||
|
|
||||||
|
def delete(self, *args, **kwargs):
|
||||||
|
if self.image:
|
||||||
|
self.image.delete(save=False)
|
||||||
|
return super().delete(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class AboutUsFeature(BaseModel):
|
||||||
|
about_us = models.ForeignKey(AboutUs, on_delete=models.CASCADE, related_name='features')
|
||||||
|
text = models.CharField(max_length=200)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.text
|
||||||
|
|
||||||
|
|
||||||
|
class Service(BaseModel):
|
||||||
|
title = models.CharField(max_length=200)
|
||||||
|
text = models.TextField()
|
||||||
|
icon = models.ImageField(upload_to='service/icons/')
|
||||||
|
image = models.ImageField(upload_to='service/images/')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.title
|
||||||
|
|
||||||
|
def delete(self, *args, **kwargs):
|
||||||
|
if self.icon:
|
||||||
|
self.icon.delete(save=False)
|
||||||
|
if self.image:
|
||||||
|
self.image.delete(save=False)
|
||||||
|
return super().delete(*args, **kwargs)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = 'Xizmatlar'
|
||||||
|
verbose_name_plural = 'Xizmatlarimiz'
|
||||||
|
|
||||||
|
|
||||||
|
class ContactUs(BaseModel):
|
||||||
|
first_name = models.CharField(max_length=200)
|
||||||
|
last_name = models.CharField(max_length=200)
|
||||||
|
phone = models.CharField(max_length=15)
|
||||||
|
email = models.EmailField()
|
||||||
|
service = models.ForeignKey(Service, on_delete=models.CASCADE, related_name='contract_us')
|
||||||
|
message = models.TextField()
|
||||||
|
is_contacted = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.email
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = 'ariza'
|
||||||
|
verbose_name_plural = 'arizalar'
|
||||||
|
|
||||||
|
|
||||||
|
class News(BaseModel):
|
||||||
|
image = models.ImageField(unique='news/images/')
|
||||||
|
title = models.CharField(max_length=300)
|
||||||
|
text = models.TextField()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.title
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = 'yangilik'
|
||||||
|
verbose_name_plural = 'yangiliklar'
|
||||||
|
|
||||||
|
|
||||||
|
class SiteConfig(BaseModel):
|
||||||
|
telegram = models.URLField()
|
||||||
|
facebook = models.URLField()
|
||||||
|
youtube = models.URLField()
|
||||||
|
instagram = models.URLField()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return 'site config'
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = 'sayt sozlamalari'
|
||||||
|
verbose_name_plural = 'sayt sozlamalari'
|
||||||
|
|||||||
31
core/apps/common/translation.py
Normal file
31
core/apps/common/translation.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
from modeltranslation import translator
|
||||||
|
|
||||||
|
from core.apps.common import models
|
||||||
|
|
||||||
|
|
||||||
|
@translator.register(models.AboutUs)
|
||||||
|
class AboutUsTranslation(translator.TranslationOptions):
|
||||||
|
fields = [
|
||||||
|
'title', 'description',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@translator.register(models.AboutUsFeature)
|
||||||
|
class AboutUsFeatureTranslation(translator.TranslationOptions):
|
||||||
|
fields = [
|
||||||
|
'text'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@translator.register(models.Service)
|
||||||
|
class ServiceTranslation(translator.TranslationOptions):
|
||||||
|
fields = [
|
||||||
|
'title', 'text',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@translator.register(models.News)
|
||||||
|
class NewsTranslation(translator.TranslationOptions):
|
||||||
|
fields = [
|
||||||
|
'title', 'text'
|
||||||
|
]
|
||||||
@@ -10,6 +10,7 @@ Django==5.2
|
|||||||
django-cacheops==7.2
|
django-cacheops==7.2
|
||||||
django-environ==0.12.0
|
django-environ==0.12.0
|
||||||
django-jazzmin==3.0.1
|
django-jazzmin==3.0.1
|
||||||
|
django-modeltranslation==0.19.16
|
||||||
django-redis==6.0.0
|
django-redis==6.0.0
|
||||||
djangorestframework==3.16.1
|
djangorestframework==3.16.1
|
||||||
djangorestframework_simplejwt==5.5.1
|
djangorestframework_simplejwt==5.5.1
|
||||||
@@ -34,3 +35,4 @@ uritemplate==4.2.0
|
|||||||
uvicorn==0.35.0
|
uvicorn==0.35.0
|
||||||
vine==5.1.0
|
vine==5.1.0
|
||||||
wcwidth==0.2.13
|
wcwidth==0.2.13
|
||||||
|
pillow
|
||||||
Reference in New Issue
Block a user