gealogiuya
This commit is contained in:
0
apps/__init__.py
Normal file
0
apps/__init__.py
Normal file
0
apps/geology/__init__.py
Normal file
0
apps/geology/__init__.py
Normal file
4
apps/geology/admin/__init__.py
Normal file
4
apps/geology/admin/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from .category import * # noqa
|
||||
from .gallery import * # noqa
|
||||
from .geology import * # noqa
|
||||
from .photo import * # noqa
|
||||
12
apps/geology/admin/category.py
Normal file
12
apps/geology/admin/category.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from django.contrib import admin
|
||||
from unfold.admin import ModelAdmin # noqa
|
||||
|
||||
from apps.geology.models import Category
|
||||
|
||||
|
||||
@admin.register(Category)
|
||||
class CategoryAdmin(ModelAdmin):
|
||||
list_display = ("name", "created_at", "updated_at")
|
||||
search_fields = ("name",)
|
||||
list_filter = ("created_at", "updated_at")
|
||||
readonly_fields = ("created_at", "updated_at")
|
||||
21
apps/geology/admin/gallery.py
Normal file
21
apps/geology/admin/gallery.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from django.contrib import admin
|
||||
from unfold.admin import ModelAdmin
|
||||
|
||||
from apps.geology.models import GalleryCategory, Gallery
|
||||
|
||||
|
||||
@admin.register(GalleryCategory)
|
||||
class GalleryCategoryAdmin(ModelAdmin):
|
||||
list_display = ("id", "name", "created_at", "updated_at")
|
||||
search_fields = ("name",)
|
||||
filter_horizontal = ("gallery",)
|
||||
list_filter = ("created_at", "updated_at")
|
||||
exclude = ("count",)
|
||||
|
||||
|
||||
@admin.register(Gallery)
|
||||
class GalleryAdmin(ModelAdmin):
|
||||
list_display = ("id", "name", "created_at", "updated_at")
|
||||
search_fields = ("name",)
|
||||
list_filter = ("created_at", "updated_at")
|
||||
exclude = ("type", "created_at", "updated_at", "name", "size")
|
||||
48
apps/geology/admin/geology.py
Normal file
48
apps/geology/admin/geology.py
Normal file
@@ -0,0 +1,48 @@
|
||||
from django.contrib import admin
|
||||
from unfold.admin import ModelAdmin # noqa
|
||||
|
||||
from apps.geology.models import Geology
|
||||
|
||||
|
||||
@admin.register(Geology)
|
||||
class GeologyAdmin(ModelAdmin):
|
||||
list_display = ("name", "category", "created_at", "updated_at")
|
||||
search_fields = ("name", "title", "body1", "body2", "body3")
|
||||
list_filter = ("category", "created_at", "updated_at")
|
||||
filter_horizontal = ("photos1", "photos2")
|
||||
readonly_fields = ("created_at", "updated_at")
|
||||
autocomplete_fields = ("category",)
|
||||
fieldsets = (
|
||||
(
|
||||
"Asosiy ma'lumotlar",
|
||||
{
|
||||
"fields": (
|
||||
"category",
|
||||
"banner_title",
|
||||
"banner",
|
||||
"name",
|
||||
"title",
|
||||
"body1",
|
||||
"address",
|
||||
"image",
|
||||
"location",
|
||||
"composition",
|
||||
"isp",
|
||||
"analysis",
|
||||
"body2",
|
||||
"photos1",
|
||||
"body3",
|
||||
"photos2",
|
||||
)
|
||||
},
|
||||
),
|
||||
(
|
||||
"Qo'shimcha ma'lumotlar",
|
||||
{
|
||||
"fields": (
|
||||
"created_at",
|
||||
"updated_at",
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
12
apps/geology/admin/photo.py
Normal file
12
apps/geology/admin/photo.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from django.contrib import admin
|
||||
from unfold.admin import ModelAdmin # noqa
|
||||
|
||||
from apps.geology.models import Photo
|
||||
|
||||
|
||||
@admin.register(Photo)
|
||||
class PhotoAdmin(ModelAdmin):
|
||||
list_display = ("name", "description", "type", "size", "image", "created_at")
|
||||
search_fields = ("name", "description", "type", "size", "image")
|
||||
list_filter = ("type",)
|
||||
exclude = ("created_at", "updated_at", "type", "size", "name")
|
||||
9
apps/geology/apps.py
Normal file
9
apps/geology/apps.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class GeologyConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "apps.geology"
|
||||
|
||||
def ready(self):
|
||||
import apps.geology.signals # noqa
|
||||
143
apps/geology/migrations/0001_initial.py
Normal file
143
apps/geology/migrations/0001_initial.py
Normal file
@@ -0,0 +1,143 @@
|
||||
# Generated by Django 5.0.8 on 2024-10-22 12:10
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="Category",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("created_at", models.DateTimeField(auto_now_add=True)),
|
||||
("updated_at", models.DateTimeField(auto_now=True)),
|
||||
("name", models.CharField(max_length=255, verbose_name="Nomi")),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Kategoriya",
|
||||
"verbose_name_plural": "Kategoriyalar",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Photo",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("created_at", models.DateTimeField(auto_now_add=True)),
|
||||
("updated_at", models.DateTimeField(auto_now=True)),
|
||||
(
|
||||
"name",
|
||||
models.CharField(
|
||||
blank=True, max_length=255, null=True, verbose_name="Nomi"
|
||||
),
|
||||
),
|
||||
(
|
||||
"description",
|
||||
models.TextField(blank=True, null=True, verbose_name="Tavsif"),
|
||||
),
|
||||
("image", models.FileField(upload_to="media/", verbose_name="Fayl")),
|
||||
(
|
||||
"type",
|
||||
models.CharField(
|
||||
blank=True, max_length=255, null=True, verbose_name="Fayl turi"
|
||||
),
|
||||
),
|
||||
(
|
||||
"size",
|
||||
models.BigIntegerField(
|
||||
blank=True, default=0, null=True, verbose_name="Hajmi"
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Foto",
|
||||
"verbose_name_plural": "Fotolar",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Geology",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("created_at", models.DateTimeField(auto_now_add=True)),
|
||||
("updated_at", models.DateTimeField(auto_now=True)),
|
||||
("name", models.CharField(max_length=255, verbose_name="Nomi")),
|
||||
("title", models.CharField(max_length=255, verbose_name="Sarlavha")),
|
||||
("body1", models.TextField(verbose_name="Tavsif1")),
|
||||
("body2", models.TextField(verbose_name="Tavsif2")),
|
||||
("body3", models.TextField(verbose_name="Tavsif3")),
|
||||
(
|
||||
"banner",
|
||||
models.ImageField(
|
||||
blank=True,
|
||||
null=True,
|
||||
upload_to="banners/",
|
||||
verbose_name="Banner",
|
||||
),
|
||||
),
|
||||
("address", models.CharField(max_length=255, verbose_name="Manzil")),
|
||||
("longitude", models.FloatField(verbose_name="Boylam")),
|
||||
("latitude", models.FloatField(verbose_name="Kenglik")),
|
||||
("composition", models.TextField(verbose_name="Tarkib")),
|
||||
("isp", models.TextField(verbose_name="ISP")),
|
||||
("analysis", models.TextField(verbose_name="Analiz")),
|
||||
(
|
||||
"category",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="cultures",
|
||||
to="geology.category",
|
||||
verbose_name="Kategoriya",
|
||||
),
|
||||
),
|
||||
(
|
||||
"photos1",
|
||||
models.ManyToManyField(
|
||||
related_name="geology_photos1",
|
||||
to="geology.photo",
|
||||
verbose_name="Fotolavhalar",
|
||||
),
|
||||
),
|
||||
(
|
||||
"photos2",
|
||||
models.ManyToManyField(
|
||||
related_name="geology_photos2",
|
||||
to="geology.photo",
|
||||
verbose_name="Fotolavhalar",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Madan",
|
||||
"verbose_name_plural": "Madanlar",
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,42 @@
|
||||
# Generated by Django 5.0.8 on 2024-10-26 07:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("geology", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name="category",
|
||||
options={
|
||||
"ordering": ["-created_at"],
|
||||
"verbose_name": "Kategoriya",
|
||||
"verbose_name_plural": "Kategoriyalar",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name="geology",
|
||||
options={
|
||||
"ordering": ["-created_at"],
|
||||
"verbose_name": "Madan",
|
||||
"verbose_name_plural": "Madanlar",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name="photo",
|
||||
options={
|
||||
"ordering": ["-created_at"],
|
||||
"verbose_name": "Foto",
|
||||
"verbose_name_plural": "Fotolar",
|
||||
},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="photo",
|
||||
name="image",
|
||||
field=models.ImageField(upload_to="media/", verbose_name="Fayl"),
|
||||
),
|
||||
]
|
||||
20
apps/geology/migrations/0003_geology_banner_title.py
Normal file
20
apps/geology/migrations/0003_geology_banner_title.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 5.0.8 on 2024-10-26 07:49
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("geology", "0002_alter_category_options_alter_geology_options_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="geology",
|
||||
name="banner_title",
|
||||
field=models.CharField(
|
||||
blank=True, max_length=255, null=True, verbose_name="Banner sarlavhasi"
|
||||
),
|
||||
),
|
||||
]
|
||||
87
apps/geology/migrations/0004_gallery_gallerycategory.py
Normal file
87
apps/geology/migrations/0004_gallery_gallerycategory.py
Normal file
@@ -0,0 +1,87 @@
|
||||
# Generated by Django 5.0.8 on 2024-10-26 10:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("geology", "0003_geology_banner_title"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="Gallery",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("created_at", models.DateTimeField(auto_now_add=True)),
|
||||
("updated_at", models.DateTimeField(auto_now=True)),
|
||||
(
|
||||
"name",
|
||||
models.CharField(
|
||||
blank=True, max_length=255, null=True, verbose_name="Nomi"
|
||||
),
|
||||
),
|
||||
(
|
||||
"description",
|
||||
models.TextField(blank=True, null=True, verbose_name="Tavsif"),
|
||||
),
|
||||
("image", models.ImageField(upload_to="media/", verbose_name="Fayl")),
|
||||
(
|
||||
"type",
|
||||
models.CharField(
|
||||
blank=True, max_length=255, null=True, verbose_name="Fayl turi"
|
||||
),
|
||||
),
|
||||
(
|
||||
"size",
|
||||
models.BigIntegerField(
|
||||
blank=True, default=0, null=True, verbose_name="Hajmi"
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Galereya",
|
||||
"verbose_name_plural": "Galereya",
|
||||
"ordering": ["-created_at"],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="GalleryCategory",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("created_at", models.DateTimeField(auto_now_add=True)),
|
||||
("updated_at", models.DateTimeField(auto_now=True)),
|
||||
("name", models.CharField(max_length=255, verbose_name="Nomi")),
|
||||
(
|
||||
"gallery",
|
||||
models.ManyToManyField(
|
||||
related_name="gallery_category",
|
||||
to="geology.gallery",
|
||||
verbose_name="Galereya",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Galereya kategoriya",
|
||||
"verbose_name_plural": "Galereya kategoriyalar",
|
||||
"ordering": ["-created_at"],
|
||||
},
|
||||
),
|
||||
]
|
||||
18
apps/geology/migrations/0005_gallerycategory_count.py
Normal file
18
apps/geology/migrations/0005_gallerycategory_count.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.8 on 2024-10-26 10:47
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("geology", "0004_gallery_gallerycategory"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="gallerycategory",
|
||||
name="count",
|
||||
field=models.BigIntegerField(default=0, verbose_name="Soni"),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,94 @@
|
||||
# Generated by Django 5.0.8 on 2024-11-02 04:41
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("geology", "0005_gallerycategory_count"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="address",
|
||||
field=models.CharField(max_length=255, verbose_name="Олинган жойи"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="analysis",
|
||||
field=models.TextField(
|
||||
verbose_name="Тоғ жинсининг спектрал тахлил натижаси (%)"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="body1",
|
||||
field=models.TextField(verbose_name="Tavsif"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="body2",
|
||||
field=models.TextField(
|
||||
verbose_name="Тоғ жинсининг шаффоф шакилда кўриниши"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="body3",
|
||||
field=models.TextField(verbose_name="Тоғ жинсининг аншлифда кўриниши"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="composition",
|
||||
field=models.TextField(verbose_name="Тог жинсининг кимёвий таркиби (%)"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="isp",
|
||||
field=models.TextField(
|
||||
verbose_name="Тоғ жинсининг ISP - масс-спектрометрик"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="latitude",
|
||||
field=models.FloatField(verbose_name="Kenglik (Координаталари)"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="longitude",
|
||||
field=models.FloatField(verbose_name="Boylam (Координаталари)"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="name",
|
||||
field=models.CharField(
|
||||
max_length=255, verbose_name="Nomi (Пироксенли скарн)"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="photos1",
|
||||
field=models.ManyToManyField(
|
||||
related_name="geology_photos1",
|
||||
to="geology.photo",
|
||||
verbose_name="Барча кўрнишлар",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="photos2",
|
||||
field=models.ManyToManyField(
|
||||
related_name="geology_photos2",
|
||||
to="geology.photo",
|
||||
verbose_name="Барча кўрнишлар",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="title",
|
||||
field=models.CharField(max_length=255, verbose_name="Sarlavha (Dr-1)"),
|
||||
),
|
||||
]
|
||||
21
apps/geology/migrations/0007_alter_photo_options.py
Normal file
21
apps/geology/migrations/0007_alter_photo_options.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# Generated by Django 5.0.8 on 2024-11-02 04:51
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("geology", "0006_alter_geology_address_alter_geology_analysis_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name="photo",
|
||||
options={
|
||||
"ordering": ["-created_at"],
|
||||
"verbose_name": "Барча кўрнишлар",
|
||||
"verbose_name_plural": "Барча кўрнишлар",
|
||||
},
|
||||
),
|
||||
]
|
||||
23
apps/geology/migrations/0008_geology_image.py
Normal file
23
apps/geology/migrations/0008_geology_image.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 5.0.8 on 2024-11-02 05:07
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("geology", "0007_alter_photo_options"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="geology",
|
||||
name="image",
|
||||
field=models.ImageField(
|
||||
blank=True,
|
||||
null=True,
|
||||
upload_to="images/",
|
||||
verbose_name="Олинган жойи сурати",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,95 @@
|
||||
# Generated by Django 5.0.8 on 2024-11-06 12:18
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("geology", "0008_geology_image"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name="geology",
|
||||
name="latitude",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="geology",
|
||||
name="longitude",
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="geology",
|
||||
name="location",
|
||||
field=models.CharField(
|
||||
blank=True, max_length=255, null=True, verbose_name="Кординаталар"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="address",
|
||||
field=models.CharField(
|
||||
blank=True, max_length=255, null=True, verbose_name="Олинган жойи"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="analysis",
|
||||
field=models.TextField(
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name="Тоғ жинсининг спектрал тахлил натижаси (%)",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="body1",
|
||||
field=models.TextField(
|
||||
blank=True, null=True, verbose_name="Тог жинсининг макроскопик таснифи"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="body2",
|
||||
field=models.TextField(
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name="Тоғ жинсининг шаффоф шлифда кўриниши",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="body3",
|
||||
field=models.TextField(
|
||||
blank=True, null=True, verbose_name="Тоғ жинсининг аншлифда кўриниши"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="composition",
|
||||
field=models.TextField(
|
||||
blank=True, null=True, verbose_name="Тог жинсининг кимёвий таркиби (%)"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="isp",
|
||||
field=models.TextField(
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name="Тоғ жинсининг ISP - масс-спектрометрик тахлил натижаси (г/т)",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="name",
|
||||
field=models.CharField(max_length=255, verbose_name="Тог жинси номи"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="title",
|
||||
field=models.CharField(
|
||||
max_length=255, verbose_name="Тог жинсининг геологик раками"
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,33 @@
|
||||
# Generated by Django 5.0.8 on 2024-11-20 07:05
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("geology", "0009_remove_geology_latitude_remove_geology_longitude_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="photos1",
|
||||
field=models.ManyToManyField(
|
||||
blank=True,
|
||||
related_name="geology_photos1",
|
||||
to="geology.photo",
|
||||
verbose_name="Барча кўрнишлар",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="geology",
|
||||
name="photos2",
|
||||
field=models.ManyToManyField(
|
||||
blank=True,
|
||||
related_name="geology_photos2",
|
||||
to="geology.photo",
|
||||
verbose_name="Барча кўрнишлар",
|
||||
),
|
||||
),
|
||||
]
|
||||
0
apps/geology/migrations/__init__.py
Normal file
0
apps/geology/migrations/__init__.py
Normal file
4
apps/geology/models/__init__.py
Normal file
4
apps/geology/models/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from .category import * # noqa
|
||||
from .gallery import * # noqa
|
||||
from .geology import * # noqa
|
||||
from .photo import * # noqa
|
||||
16
apps/geology/models/category.py
Normal file
16
apps/geology/models/category.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from apps.shared.models import AbstractBaseModel
|
||||
|
||||
|
||||
class Category(AbstractBaseModel):
|
||||
name = models.CharField(max_length=255, verbose_name=_("Nomi"))
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Kategoriya")
|
||||
verbose_name_plural = _("Kategoriyalar")
|
||||
ordering = ["-created_at"]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.name
|
||||
20
apps/geology/models/gallery.py
Normal file
20
apps/geology/models/gallery.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from apps.shared.models import AbstractBaseModel
|
||||
|
||||
|
||||
class GalleryCategory(AbstractBaseModel):
|
||||
name = models.CharField(max_length=255, verbose_name=_("Nomi"))
|
||||
count = models.BigIntegerField(default=0, verbose_name=_("Soni"))
|
||||
gallery = models.ManyToManyField(
|
||||
"Gallery", related_name="gallery_category", verbose_name=_("Galereya")
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Galereya kategoriya")
|
||||
verbose_name_plural = _("Galereya kategoriyalar")
|
||||
ordering = ["-created_at"]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.name
|
||||
47
apps/geology/models/geology.py
Normal file
47
apps/geology/models/geology.py
Normal file
@@ -0,0 +1,47 @@
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from apps.shared.models import AbstractBaseModel
|
||||
|
||||
|
||||
class Geology(AbstractBaseModel):
|
||||
category = models.ForeignKey(
|
||||
"Category",
|
||||
on_delete=models.CASCADE,
|
||||
related_name="cultures",
|
||||
verbose_name=_("Kategoriya"),
|
||||
)
|
||||
banner_title = models.CharField(
|
||||
max_length=255, verbose_name=_("Banner sarlavhasi"), null=True, blank=True
|
||||
)
|
||||
banner = models.ImageField(
|
||||
upload_to="banners/", verbose_name=_("Banner"), null=True, blank=True
|
||||
)
|
||||
name = models.CharField(max_length=255, verbose_name=_("Тог жинси номи"))
|
||||
title = models.CharField(max_length=255, verbose_name=_("Тог жинсининг геологик раками"))
|
||||
body1 = models.TextField(verbose_name=_("Тог жинсининг макроскопик таснифи"), null=True, blank=True)
|
||||
address = models.CharField(max_length=255, verbose_name=_("Олинган жойи"), null=True, blank=True)
|
||||
image = models.ImageField(upload_to="images/", verbose_name=_("Олинган жойи сурати"), null=True, blank=True)
|
||||
location = models.CharField(max_length=255, verbose_name=_("Кординаталар"), null=True, blank=True)
|
||||
composition = models.TextField(verbose_name=_("Тог жинсининг кимёвий таркиби (%)"), null=True, blank=True)
|
||||
isp = models.TextField(verbose_name=_("Тоғ жинсининг ISP - масс-спектрометрик тахлил натижаси (г/т)"), null=True,
|
||||
blank=True)
|
||||
analysis = models.TextField(
|
||||
verbose_name=_("Тоғ жинсининг спектрал тахлил натижаси (%)"), null=True, blank=True
|
||||
)
|
||||
body2 = models.TextField(verbose_name=_("Тоғ жинсининг шаффоф шлифда кўриниши"), null=True, blank=True)
|
||||
photos1 = models.ManyToManyField(
|
||||
"Photo", verbose_name=_("Барча кўрнишлар"), related_name="geology_photos1", blank=True
|
||||
)
|
||||
body3 = models.TextField(verbose_name=_("Тоғ жинсининг аншлифда кўриниши"), null=True, blank=True)
|
||||
photos2 = models.ManyToManyField(
|
||||
"Photo", verbose_name=_("Барча кўрнишлар"), related_name="geology_photos2", blank=True
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Madan")
|
||||
verbose_name_plural = _("Madanlar")
|
||||
ordering = ["-created_at"]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.name
|
||||
66
apps/geology/models/photo.py
Normal file
66
apps/geology/models/photo.py
Normal file
@@ -0,0 +1,66 @@
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from apps.shared.models import AbstractBaseModel
|
||||
|
||||
|
||||
class Photo(AbstractBaseModel):
|
||||
name = models.CharField(
|
||||
max_length=255, blank=True, null=True, verbose_name=_("Nomi")
|
||||
)
|
||||
description = models.TextField(blank=True, null=True, verbose_name=_("Tavsif"))
|
||||
image = models.ImageField(upload_to="media/", verbose_name=_("Fayl"))
|
||||
type = models.CharField(
|
||||
max_length=255, blank=True, null=True, verbose_name=_("Fayl turi")
|
||||
)
|
||||
size = models.BigIntegerField(
|
||||
blank=True, null=True, default=0, verbose_name=_("Hajmi")
|
||||
)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.type = self.image.name.split(".")[-1]
|
||||
self.size = self.image.size
|
||||
if self.name is None:
|
||||
self.name = (
|
||||
self.image.name if self.image.name is not None else f"Media {self.id}"
|
||||
)
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Барча кўрнишлар")
|
||||
verbose_name_plural = _("Барча кўрнишлар")
|
||||
ordering = ["-created_at"]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return str(self.description) if str(self.description) else f"Photo {self.id}"
|
||||
|
||||
|
||||
class Gallery(AbstractBaseModel):
|
||||
name = models.CharField(
|
||||
max_length=255, blank=True, null=True, verbose_name=_("Nomi")
|
||||
)
|
||||
description = models.TextField(blank=True, null=True, verbose_name=_("Tavsif"))
|
||||
image = models.ImageField(upload_to="media/", verbose_name=_("Fayl"))
|
||||
type = models.CharField(
|
||||
max_length=255, blank=True, null=True, verbose_name=_("Fayl turi")
|
||||
)
|
||||
size = models.BigIntegerField(
|
||||
blank=True, null=True, default=0, verbose_name=_("Hajmi")
|
||||
)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.type = self.image.name.split(".")[-1]
|
||||
self.size = self.image.size
|
||||
if self.name is None:
|
||||
self.name = (
|
||||
self.image.name if self.image.name is not None else f"Media {self.id}"
|
||||
)
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Galereya")
|
||||
verbose_name_plural = _("Galereya")
|
||||
ordering = ["-created_at"]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return str(self.description) if str(self.description) else f"Gallery {self.id}"
|
||||
4
apps/geology/serializers/__init__.py
Normal file
4
apps/geology/serializers/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from .category import * # noqa
|
||||
from .gallery import * # noqa
|
||||
from .geology import * # noqa
|
||||
from .photo import * # noqa
|
||||
16
apps/geology/serializers/category.py
Normal file
16
apps/geology/serializers/category.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from typing import Type
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from apps.geology.models import Category, Geology
|
||||
|
||||
|
||||
class CategorySerializer(serializers.ModelSerializer):
|
||||
count = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model: Type[Category] = Category
|
||||
fields: str = ("id", "count", "name", "created_at", "updated_at")
|
||||
|
||||
def get_count(self, obj):
|
||||
return Geology.objects.filter(category=obj).count()
|
||||
17
apps/geology/serializers/gallery.py
Normal file
17
apps/geology/serializers/gallery.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from rest_framework import serializers
|
||||
|
||||
from apps.geology.models import Gallery, GalleryCategory
|
||||
|
||||
|
||||
class GallerySerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Gallery
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class GalleryCategorySerializer(serializers.ModelSerializer):
|
||||
gallery = GallerySerializer(many=True, read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = GalleryCategory
|
||||
fields = ("id", "name", "count", "gallery", "created_at", "updated_at")
|
||||
161
apps/geology/serializers/geology.py
Normal file
161
apps/geology/serializers/geology.py
Normal file
@@ -0,0 +1,161 @@
|
||||
import logging
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from drf_spectacular.utils import extend_schema_field
|
||||
from rest_framework import exceptions, status
|
||||
from rest_framework import serializers
|
||||
from rest_framework.response import Response
|
||||
|
||||
from apps.geology.models import Geology, Photo
|
||||
|
||||
|
||||
class GeologySerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Geology
|
||||
fields = (
|
||||
"id",
|
||||
"name",
|
||||
"title",
|
||||
"body1",
|
||||
"body2",
|
||||
"body3",
|
||||
"banner_title",
|
||||
"banner",
|
||||
"address",
|
||||
"image",
|
||||
"location",
|
||||
"composition",
|
||||
"isp",
|
||||
"analysis",
|
||||
"category",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
)
|
||||
|
||||
def create(self, validated_data):
|
||||
try:
|
||||
request = self.context.get("request")
|
||||
photo_data1 = []
|
||||
photo_data2 = []
|
||||
|
||||
for key in request.data:
|
||||
if key.startswith("description1[") and key.endswith("]"):
|
||||
index = key[len("description1[") : -1]
|
||||
file_key = f"image1[{index}]"
|
||||
photo_desc = request.data.get(key)
|
||||
photo_file = request.FILES.get(file_key)
|
||||
|
||||
if not photo_file:
|
||||
return Response(
|
||||
{
|
||||
"error": f"File is required for photo item {index} in photos1"
|
||||
},
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
if not photo_desc:
|
||||
photo_desc = photo_file.name
|
||||
photo_data1.append({"image": photo_file, "description": photo_desc})
|
||||
|
||||
if key.startswith("description2[") and key.endswith("]"):
|
||||
index = key[len("description2[") : -1]
|
||||
file_key = f"image2[{index}]"
|
||||
photo_desc = request.data.get(key)
|
||||
photo_file = request.FILES.get(file_key)
|
||||
|
||||
if not photo_file:
|
||||
return Response(
|
||||
{
|
||||
"error": f"File is required for photo item {index} in photos2"
|
||||
},
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
if not photo_desc:
|
||||
photo_desc = photo_file.name
|
||||
photo_data2.append({"image": photo_file, "description": photo_desc})
|
||||
|
||||
geology = Geology.objects.create(
|
||||
name=validated_data.get("name"),
|
||||
title=validated_data.get("title"),
|
||||
body1=validated_data.get("body1"),
|
||||
body2=validated_data.get("body2"),
|
||||
body3=validated_data.get("body3"),
|
||||
banner_title=validated_data.get("banner_title"),
|
||||
banner=validated_data.get("banner"),
|
||||
address=validated_data.get("address"),
|
||||
location=validated_data.get("location"),
|
||||
composition=validated_data.get("composition"),
|
||||
isp=validated_data.get("isp"),
|
||||
analysis=validated_data.get("analysis"),
|
||||
category=validated_data.get("category"),
|
||||
)
|
||||
|
||||
for photo in photo_data1:
|
||||
photo_instance = Photo.objects.create(
|
||||
image=photo["image"], description=photo["description"]
|
||||
)
|
||||
geology.photos1.add(photo_instance)
|
||||
|
||||
for photo in photo_data2:
|
||||
photo_instance = Photo.objects.create(
|
||||
image=photo["image"], description=photo["description"]
|
||||
)
|
||||
geology.photos2.add(photo_instance)
|
||||
return geology
|
||||
except Exception as e:
|
||||
logging.error(f"Error in create method: {str(e)}")
|
||||
raise exceptions.ValidationError({"detail": str(e)})
|
||||
|
||||
|
||||
class GeologyDetailSerializer(serializers.ModelSerializer):
|
||||
category = serializers.SerializerMethodField()
|
||||
photos1 = serializers.SerializerMethodField()
|
||||
photos2 = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Geology
|
||||
fields = (
|
||||
"id",
|
||||
"category",
|
||||
"banner_title",
|
||||
"banner",
|
||||
"name",
|
||||
"title",
|
||||
"body1",
|
||||
"address",
|
||||
"image",
|
||||
"location",
|
||||
"composition",
|
||||
"isp",
|
||||
"analysis",
|
||||
"body2",
|
||||
"photos1",
|
||||
"body3",
|
||||
"photos2",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
)
|
||||
|
||||
def to_representation(self, instance):
|
||||
representation = super().to_representation(instance)
|
||||
if representation.get("banner"):
|
||||
parsed_url = urlparse(representation["banner"])
|
||||
representation["banner"] = parsed_url.path
|
||||
return representation
|
||||
|
||||
@extend_schema_field(serializers.DictField())
|
||||
def get_category(self, obj):
|
||||
from apps.geology.serializers.category import CategorySerializer
|
||||
|
||||
return CategorySerializer(obj.category).data
|
||||
|
||||
@extend_schema_field(serializers.ListField(child=serializers.DictField()))
|
||||
def get_photos1(self, obj):
|
||||
from apps.geology.serializers.photo import PhotoSerializer
|
||||
|
||||
return PhotoSerializer(obj.photos1.all(), many=True).data
|
||||
|
||||
@extend_schema_field(serializers.ListField(child=serializers.DictField()))
|
||||
def get_photos2(self, obj):
|
||||
from apps.geology.serializers.photo import PhotoSerializer
|
||||
|
||||
return PhotoSerializer(obj.photos2.all(), many=True).data
|
||||
11
apps/geology/serializers/photo.py
Normal file
11
apps/geology/serializers/photo.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from typing import Type
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from apps.geology.models import Photo
|
||||
|
||||
|
||||
class PhotoSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model: Type[Photo] = Photo
|
||||
fields: str = "__all__"
|
||||
1
apps/geology/signals/__init__.py
Normal file
1
apps/geology/signals/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .gallery import * # noqa
|
||||
12
apps/geology/signals/gallery.py
Normal file
12
apps/geology/signals/gallery.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from django.db.models.signals import m2m_changed
|
||||
from django.dispatch import receiver
|
||||
|
||||
from apps.geology.models import GalleryCategory
|
||||
|
||||
|
||||
@receiver(m2m_changed, sender=GalleryCategory.gallery.through)
|
||||
def gallery_category_m2m_changed(sender, instance, action, **kwargs):
|
||||
if action in ["post_add", "post_remove", "post_clear"]:
|
||||
instance.count = instance.gallery.count()
|
||||
print(instance.count)
|
||||
instance.save()
|
||||
0
apps/geology/tests/__init__.py
Normal file
0
apps/geology/tests/__init__.py
Normal file
12
apps/geology/urls.py
Normal file
12
apps/geology/urls.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from typing import List
|
||||
|
||||
from django.urls import path
|
||||
from django.urls.resolvers import URLPattern
|
||||
|
||||
from apps.geology.views import GeologyView, CategoryView, GalleryCategoryView
|
||||
|
||||
urlpatterns: List[URLPattern] = [
|
||||
path("geology/", GeologyView.as_view(), name="geology"),
|
||||
path("category/", CategoryView.as_view(), name="category"),
|
||||
path("gallery/", GalleryCategoryView.as_view(), name="gallery"),
|
||||
]
|
||||
3
apps/geology/views/__init__.py
Normal file
3
apps/geology/views/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from .category import * # noqa
|
||||
from .gallery import * # noqa
|
||||
from .geology import * # noqa
|
||||
24
apps/geology/views/category.py
Normal file
24
apps/geology/views/category.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from typing import Type
|
||||
|
||||
from django.db.models import QuerySet
|
||||
from rest_framework.generics import GenericAPIView
|
||||
from rest_framework.permissions import AllowAny
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.serializers import Serializer
|
||||
|
||||
from apps.geology.models import Category
|
||||
from apps.geology.serializers import CategorySerializer
|
||||
|
||||
|
||||
class CategoryView(GenericAPIView):
|
||||
permission_classes = [AllowAny]
|
||||
serializer_class: Type[Serializer] = CategorySerializer
|
||||
|
||||
def get_queryset(self) -> QuerySet[Category]:
|
||||
return Category.objects.all()
|
||||
|
||||
def get(self, request: Request) -> Response:
|
||||
categories = self.get_queryset()
|
||||
serializer = self.serializer_class(categories, many=True)
|
||||
return Response(serializer.data)
|
||||
24
apps/geology/views/gallery.py
Normal file
24
apps/geology/views/gallery.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from typing import Type
|
||||
|
||||
from django.db.models import QuerySet
|
||||
from rest_framework.generics import GenericAPIView
|
||||
from rest_framework.permissions import AllowAny
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.serializers import Serializer
|
||||
|
||||
from apps.geology.models import GalleryCategory
|
||||
from apps.geology.serializers import GalleryCategorySerializer
|
||||
|
||||
|
||||
class GalleryCategoryView(GenericAPIView):
|
||||
permission_classes = [AllowAny]
|
||||
serializer_class: Type[Serializer] = GalleryCategorySerializer
|
||||
|
||||
def get_queryset(self) -> QuerySet[GalleryCategory]:
|
||||
return GalleryCategory.objects.all()
|
||||
|
||||
def get(self, request: Request) -> Response:
|
||||
categories = self.get_queryset()
|
||||
serializer = self.serializer_class(categories, many=True)
|
||||
return Response(serializer.data)
|
||||
45
apps/geology/views/geology.py
Normal file
45
apps/geology/views/geology.py
Normal file
@@ -0,0 +1,45 @@
|
||||
from typing import Type
|
||||
|
||||
from django.db.models import QuerySet
|
||||
from rest_framework import status
|
||||
from rest_framework.generics import GenericAPIView
|
||||
from rest_framework.permissions import AllowAny
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.serializers import Serializer
|
||||
|
||||
from apps.geology.models import Geology
|
||||
from apps.geology.serializers import GeologySerializer, GeologyDetailSerializer
|
||||
|
||||
|
||||
class GeologyView(GenericAPIView):
|
||||
permission_classes = [AllowAny]
|
||||
|
||||
def get_serializer_class(self) -> Type[Serializer]:
|
||||
if self.request.method == "POST":
|
||||
return GeologySerializer
|
||||
return GeologyDetailSerializer
|
||||
|
||||
def get_queryset(self) -> QuerySet[Geology]:
|
||||
return Geology.objects.all().select_related()
|
||||
|
||||
def get(self, request: Request) -> Response:
|
||||
geology_id = request.query_params.get("id")
|
||||
category_id = request.query_params.get("category")
|
||||
if geology_id:
|
||||
geologies = Geology.objects.filter(id=geology_id)
|
||||
elif category_id:
|
||||
geologies = Geology.objects.filter(category_id=category_id)
|
||||
else:
|
||||
geologies = self.get_queryset()
|
||||
serializer = self.get_serializer(geologies, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
def post(self, request: Request) -> Response:
|
||||
serializer = self.get_serializer(
|
||||
data=request.data, context={"request": request}
|
||||
)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
0
apps/shared/__init__.py
Normal file
0
apps/shared/__init__.py
Normal file
33
apps/shared/admin.py
Normal file
33
apps/shared/admin.py
Normal file
@@ -0,0 +1,33 @@
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth.admin import GroupAdmin as BaseGroupAdmin
|
||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
||||
from django.contrib.auth.models import Group, User
|
||||
from unfold.admin import ModelAdmin # noqa
|
||||
from unfold.forms import (
|
||||
UserChangeForm,
|
||||
UserCreationForm,
|
||||
AdminPasswordChangeForm,
|
||||
) # noqa
|
||||
|
||||
admin.site.unregister(Group)
|
||||
admin.site.unregister(User)
|
||||
|
||||
|
||||
@admin.register(Group)
|
||||
class GroupAdmin(BaseGroupAdmin, ModelAdmin):
|
||||
list_display = ("name",)
|
||||
search_fields = ("name",)
|
||||
filter_vertical = ("permissions",)
|
||||
|
||||
|
||||
@admin.register(User)
|
||||
class UserAdmin(BaseUserAdmin, ModelAdmin):
|
||||
change_password_form = AdminPasswordChangeForm
|
||||
add_form = UserCreationForm
|
||||
form = UserChangeForm
|
||||
list_display = ("username", "email", "is_active", "is_staff", "is_superuser")
|
||||
list_filter = ("is_active", "is_staff", "is_superuser")
|
||||
search_fields = ("username", "email")
|
||||
ordering = ("username",)
|
||||
list_editable = ("is_active", "is_staff", "is_superuser")
|
||||
filter_vertical = ("groups", "user_permissions")
|
||||
6
apps/shared/apps.py
Normal file
6
apps/shared/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class SharedConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "apps.shared"
|
||||
0
apps/shared/management/__init__.py
Normal file
0
apps/shared/management/__init__.py
Normal file
0
apps/shared/management/commands/__init__.py
Normal file
0
apps/shared/management/commands/__init__.py
Normal file
25
apps/shared/management/commands/createadmin.py
Normal file
25
apps/shared/management/commands/createadmin.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
def handle(self, *args, **options):
|
||||
user = get_user_model()
|
||||
self.create_superuser(user, "jahongir", "jahongirhakimjonov@gmail.com", "1253")
|
||||
self.create_superuser(
|
||||
user, "Jahongir", "jahongirhakimjonov@gmail.com", "20030307mart"
|
||||
)
|
||||
self.create_superuser(
|
||||
user, "998330078587", "jahongirhakimjonov@gmail.com", "20030307mart"
|
||||
)
|
||||
|
||||
def create_superuser(self, user, username, email, password):
|
||||
if not user.objects.filter(username=username).exists():
|
||||
user.objects.create_superuser(username, email, password)
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(f"Superuser {username} created successfully.")
|
||||
)
|
||||
else:
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(f"Superuser {username} already exists.")
|
||||
)
|
||||
52
apps/shared/management/commands/makeapp.py
Normal file
52
apps/shared/management/commands/makeapp.py
Normal file
@@ -0,0 +1,52 @@
|
||||
import os
|
||||
|
||||
from django.core.management import call_command
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = (
|
||||
"Creates a new Django app inside the apps folder and sets the name in apps.py"
|
||||
)
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument("app_name", type=str, help="The name of the app to create")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
app_name = options["app_name"]
|
||||
app_directory = os.path.join("apps", app_name)
|
||||
|
||||
os.makedirs(app_directory, exist_ok=True)
|
||||
|
||||
init_file_path = os.path.join("apps", "__init__.py")
|
||||
|
||||
if not os.path.exists(init_file_path):
|
||||
open(init_file_path, "w").close()
|
||||
|
||||
call_command("startapp", app_name, app_directory)
|
||||
|
||||
apps_file_path = os.path.join(app_directory, "apps.py")
|
||||
with open(apps_file_path, "r") as file:
|
||||
filedata = file.read()
|
||||
|
||||
filedata = filedata.replace(f'name = "{app_name}"', f'name = "apps.{app_name}"')
|
||||
|
||||
with open(apps_file_path, "w") as file:
|
||||
file.write(filedata)
|
||||
|
||||
for file_name in ["admin.py", "models.py", "views.py", "tests.py"]:
|
||||
os.remove(os.path.join(app_directory, file_name))
|
||||
|
||||
urls_file_path = os.path.join(app_directory, "urls.py")
|
||||
with open(urls_file_path, "w") as file:
|
||||
file.write("from django.urls import path\n\nurlpatterns = []\n")
|
||||
|
||||
def create_package(package_name): # noqa
|
||||
os.makedirs(package_name, exist_ok=True)
|
||||
with open(os.path.join(package_name, "__init__.py"), "w"):
|
||||
pass
|
||||
|
||||
for package_name in ["models", "views", "admin", "serializers", "tests"]:
|
||||
create_package(os.path.join(app_directory, package_name))
|
||||
|
||||
self.stdout.write(self.style.SUCCESS(f"App {app_name} created successfully!"))
|
||||
43
apps/shared/management/commands/nginx.py
Normal file
43
apps/shared/management/commands/nginx.py
Normal file
@@ -0,0 +1,43 @@
|
||||
import os
|
||||
|
||||
from colorama import Fore, Style
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Generates a new nginx config file with custom domain and project path"
|
||||
|
||||
def handle(self, *args, **kwargs):
|
||||
domain_name = input(
|
||||
Fore.LIGHTCYAN_EX + "Please enter the domain name: " + Style.RESET_ALL
|
||||
)
|
||||
project_name = input(
|
||||
Fore.LIGHTMAGENTA_EX + "\nPlease enter the project name: " + Style.RESET_ALL
|
||||
)
|
||||
project_port = input(
|
||||
Fore.LIGHTBLUE_EX + "\nPlease enter the project port: " + Style.RESET_ALL
|
||||
)
|
||||
|
||||
source_file_path = "./deployments/compose/nginx/nginx.conf"
|
||||
target_dir_path = "./deployments/nginx"
|
||||
target_file_path = f"{target_dir_path}/{domain_name}.conf"
|
||||
|
||||
with open(source_file_path, "r") as file:
|
||||
file_contents = file.read()
|
||||
|
||||
file_contents = file_contents.replace("yourdomain.uz", domain_name)
|
||||
file_contents = file_contents.replace("/path/project", project_name)
|
||||
file_contents = file_contents.replace("PROJECT_PORT", project_port)
|
||||
|
||||
os.makedirs(target_dir_path, exist_ok=True)
|
||||
|
||||
with open(target_file_path, "w") as file:
|
||||
file.write(file_contents)
|
||||
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
Fore.LIGHTGREEN_EX
|
||||
+ f"\n\n\nSuccessfully created {target_file_path}\n\n"
|
||||
+ Style.RESET_ALL
|
||||
)
|
||||
)
|
||||
21
apps/shared/management/commands/secret_key.py
Normal file
21
apps/shared/management/commands/secret_key.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from colorama import Fore, Style
|
||||
from django.core.management import utils
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Generates a new Django secret key"
|
||||
|
||||
def handle(self, *args, **options):
|
||||
print(
|
||||
Fore.LIGHTCYAN_EX
|
||||
+ "<======================================================>"
|
||||
)
|
||||
print(
|
||||
"<=" + Style.RESET_ALL,
|
||||
Fore.LIGHTMAGENTA_EX + utils.get_random_secret_key() + Style.RESET_ALL,
|
||||
Fore.LIGHTCYAN_EX + "=>",
|
||||
)
|
||||
print(
|
||||
"<======================================================>" + Style.RESET_ALL
|
||||
)
|
||||
0
apps/shared/migrations/__init__.py
Normal file
0
apps/shared/migrations/__init__.py
Normal file
9
apps/shared/models.py
Normal file
9
apps/shared/models.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from django.db import models
|
||||
|
||||
|
||||
class AbstractBaseModel(models.Model):
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
1
apps/shared/tests.py
Normal file
1
apps/shared/tests.py
Normal file
@@ -0,0 +1 @@
|
||||
# Create your tests here.
|
||||
6
apps/shared/urls.py
Normal file
6
apps/shared/urls.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.urls import path
|
||||
from .views import HomeView
|
||||
|
||||
urlpatterns = [
|
||||
path("", HomeView.as_view(), name="home"),
|
||||
]
|
||||
5
apps/shared/views.py
Normal file
5
apps/shared/views.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
|
||||
class HomeView(TemplateView):
|
||||
template_name = "index.html"
|
||||
Reference in New Issue
Block a user