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 = [
|
||||
'jazzmin',
|
||||
'modeltranslation',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
@@ -117,4 +118,12 @@ EMAIL_HOST = env.str('EMAIL_HOST')
|
||||
EMAIL_PORT = env.str('EMAIL_PORT')
|
||||
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',
|
||||
),
|
||||
]
|
||||
@@ -8,4 +8,118 @@ class BaseModel(models.Model):
|
||||
updated_at = models.DateField(auto_now=True)
|
||||
|
||||
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-environ==0.12.0
|
||||
django-jazzmin==3.0.1
|
||||
django-modeltranslation==0.19.16
|
||||
django-redis==6.0.0
|
||||
djangorestframework==3.16.1
|
||||
djangorestframework_simplejwt==5.5.1
|
||||
@@ -34,3 +35,4 @@ uritemplate==4.2.0
|
||||
uvicorn==0.35.0
|
||||
vine==5.1.0
|
||||
wcwidth==0.2.13
|
||||
pillow
|
||||
Reference in New Issue
Block a user