first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 22:20:45 +03:00
commit d50f14bcb1
681 changed files with 65020 additions and 0 deletions

0
settings/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

25
settings/admin.py Normal file
View File

@@ -0,0 +1,25 @@
from django.contrib import admin
from settings.models import Setting, Banner, SiteSettings
# Register your models here.
class SettingAdmin(admin.ModelAdmin):
list_display = ('title', 'is_active', 'created_at')
list_editable = ('is_active',)
admin.site.register(Setting, SettingAdmin)
class BannerAdmin(admin.ModelAdmin):
list_display = ('title', 'is_active', 'created_at')
list_editable = ('is_active',)
admin.site.register(Banner, BannerAdmin)
class SiteSettingsAdmin(admin.ModelAdmin):
list_display = ('id', 'is_active', 'site_active', 'created_at')
list_editable = ('is_active','site_active',)
admin.site.register(SiteSettings, SiteSettingsAdmin)

8
settings/apps.py Normal file
View File

@@ -0,0 +1,8 @@
from django.apps import AppConfig
class SettingsConfig(AppConfig):
name = 'settings'
def ready(self):
import settings.signals

View File

@@ -0,0 +1,68 @@
# Generated by Django 6.0 on 2025-12-13 15:41
import colorfield.fields
import imagekit.models.fields
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Banner',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('color', colorfield.fields.ColorField(default='#FFFFFF', image_field=None, max_length=25, samples=None, verbose_name='Yazı Rengi')),
('title', models.CharField(max_length=254, null=True, verbose_name='Baner Adı')),
('text1', models.CharField(max_length=254, null=True, verbose_name='Baner Küçük Yazı 1')),
('text2', models.CharField(max_length=254, null=True, verbose_name='Baner Büyük Yazı 1')),
('text4', models.CharField(max_length=254, null=True, verbose_name='Baner Küçük Yazı 2')),
('text5', models.CharField(max_length=254, null=True, verbose_name='Baner Düğme Yazısı')),
('image', imagekit.models.fields.ProcessedImageField(upload_to='uploads/banner/%Y')),
('image_k', imagekit.models.fields.ProcessedImageField(blank=True, null=True, upload_to='uploads/banner/kucuk/%Y')),
('image_k_txt', models.CharField(max_length=254, null=True, verbose_name='Küçük Resim Yazisi')),
('is_active', models.BooleanField(choices=[(True, 'Evet'), (False, 'Hayır')], default=True, verbose_name='Yayındamı ?')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Oluşturulma Tarihi')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Güncelleme Tarihi')),
],
options={
'verbose_name': 'Banner',
'verbose_name_plural': 'Bannerler',
'db_table': 'banners',
'ordering': ['-created_at'],
},
),
migrations.CreateModel(
name='Setting',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=254, verbose_name='Ayar Başlığı')),
('meta_title', models.CharField(default='Meta Title', max_length=254, verbose_name='Meta Title')),
('meta_description', models.CharField(default='Meta Description', max_length=254, verbose_name='Meta Description')),
('phone', models.CharField(max_length=254, verbose_name='Telefon')),
('url', models.CharField(blank=True, default='https://beyhanogur.com.tr', max_length=254, null=True, verbose_name='Site İnternet Adresi')),
('email', models.EmailField(max_length=254, verbose_name='E-Posta')),
('facebook', models.CharField(blank=True, default='https://www.facebook.com', max_length=254, null=True, verbose_name='Facebook')),
('x', models.CharField(blank=True, default='https://www.twitter.com', max_length=254, null=True, verbose_name='Twitter')),
('instagram', models.CharField(blank=True, default='https://www.instagram.com', max_length=254, null=True, verbose_name='Instagram')),
('whatsapp', models.CharField(blank=True, default='https://www.whatsapp.com', max_length=254, null=True, verbose_name='Whatsapp')),
('slogan', models.CharField(blank=True, default='Dondurma', max_length=254, null=True, verbose_name='Başlık Solaganı')),
('w_logo', imagekit.models.fields.ProcessedImageField(blank=True, null=True, upload_to='uploads/logo')),
('b_logo', imagekit.models.fields.ProcessedImageField(blank=True, null=True, upload_to='uploads/logo')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Oluşturulma Tarihi')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Güncelleme Tarihi')),
('is_active', models.BooleanField(choices=[(True, 'Evet'), (False, 'Hayır')], default=False, verbose_name='Yayındamı')),
],
options={
'verbose_name': 'Site Ayarı',
'verbose_name_plural': 'Site Ayarları',
'db_table': 'settings',
'ordering': ['-created_at'],
},
),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 6.0 on 2026-01-12 17:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('settings', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='setting',
name='linkedin',
field=models.CharField(blank=True, default='https://www.linkedin.com', max_length=254, null=True, verbose_name='linkedin'),
),
migrations.AddField(
model_name='setting',
name='pinterest',
field=models.CharField(blank=True, default='https://www.pinterest.com', max_length=254, null=True, verbose_name='pinterest'),
),
]

View File

@@ -0,0 +1,28 @@
# Generated by Django 6.0 on 2026-01-16 11:38
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('settings', '0002_setting_linkedin_setting_pinterest'),
]
operations = [
migrations.CreateModel(
name='SiteSettings',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('is_active', models.BooleanField(choices=[(True, 'Evet'), (False, 'Hayır')], default=True, verbose_name='Yayındamı ?')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Oluşturulma Tarihi')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Güncelleme Tarihi')),
],
options={
'verbose_name': 'Banner',
'verbose_name_plural': 'Bannerler',
'db_table': 'site_settings',
'ordering': ['-created_at'],
},
),
]

View File

@@ -0,0 +1,22 @@
# Generated by Django 6.0 on 2026-01-16 12:01
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('settings', '0003_sitesettings'),
]
operations = [
migrations.AlterModelOptions(
name='sitesettings',
options={'ordering': ['-created_at'], 'verbose_name': 'Site Ayarı Aç / Kapat', 'verbose_name_plural': 'Site Ayarları Aç / Kapat'},
),
migrations.AddField(
model_name='sitesettings',
name='site_active',
field=models.BooleanField(choices=[(True, 'Evet'), (False, 'Hayır')], default=True, verbose_name='Yayındamı ?'),
),
]

View File

99
settings/models.py Normal file
View File

@@ -0,0 +1,99 @@
from django.db import models
from colorfield.fields import ColorField
from imagekit.models import ProcessedImageField
from imagekit.processors import ResizeToFill
class Setting(models.Model):
aktif = (
(True, 'Evet'),
(False, 'Hayır'),
)
title = models.CharField(max_length=254, verbose_name="Ayar Başlığı")
meta_title = models.CharField(max_length=254, verbose_name="Meta Title", default='Meta Title')
meta_description = models.CharField(max_length=254, verbose_name="Meta Description", default='Meta Description')
phone = models.CharField(max_length=254, verbose_name="Telefon")
url = models.CharField(max_length=254, verbose_name="Site İnternet Adresi", blank=True, null=True,
default='https://beyhanogur.com.tr')
email = models.EmailField(max_length=254, verbose_name="E-Posta")
facebook = models.CharField(max_length=254, verbose_name="Facebook", default='https://www.facebook.com', null=True,
blank=True)
x = models.CharField(max_length=254, verbose_name="Twitter", default='https://www.twitter.com', null=True,
blank=True)
instagram = models.CharField(max_length=254, verbose_name="Instagram", default='https://www.instagram.com',
null=True, blank=True)
whatsapp = models.CharField(max_length=254, verbose_name="Whatsapp", default='https://www.whatsapp.com', null=True,
blank=True)
pinterest = models.CharField(max_length=254, verbose_name="pinterest", default='https://www.pinterest.com', null=True, blank=True)
linkedin = models.CharField(max_length=254, verbose_name="linkedin", default='https://www.linkedin.com', null=True, blank=True)
slogan = models.CharField(max_length=254, verbose_name="Başlık Solaganı", default='Dondurma', null=True, blank=True)
w_logo = ProcessedImageField(upload_to='uploads/logo', null=True, blank=True, processors=[ResizeToFill(165, 54)],
format='PNG', options={'quality': 85})
b_logo = ProcessedImageField(upload_to='uploads/logo', null=True, blank=True, processors=[ResizeToFill(165, 54)],
format='PNG', options={'quality': 85})
created_at = models.DateTimeField(auto_now_add=True, editable=False, verbose_name="Oluşturulma Tarihi")
updated_at = models.DateTimeField(auto_now=True, editable=False, verbose_name="Güncelleme Tarihi")
is_active = models.BooleanField(default=False, verbose_name='Yayındamı', choices=aktif)
class Meta:
ordering = ["-created_at"]
db_table = 'settings'
verbose_name_plural = "Site Ayarları"
verbose_name = "Site Ayarı"
def __str__(self):
return self.title
class Banner(models.Model):
aktif = (
(True, 'Evet'),
(False, 'Hayır'),
)
color = ColorField(default='#FFFFFF', verbose_name='Yazı Rengi')
title = models.CharField(max_length=254, verbose_name='Baner Adı', null=True)
text1 = models.CharField(max_length=254, verbose_name='Baner Küçük Yazı 1', null=True)
text2 = models.CharField(max_length=254, verbose_name='Baner Büyük Yazı 1', null=True)
text4 = models.CharField(max_length=254, verbose_name='Baner Küçük Yazı 2', null=True)
text5 = models.CharField(max_length=254, verbose_name='Baner Düğme Yazısı', null=True)
image = ProcessedImageField(upload_to='uploads/banner/%Y',
processors=[ResizeToFill(1880, 950)],
format='JPEG',
options={'quality': 90})
image_k = ProcessedImageField(upload_to='uploads/banner/kucuk/%Y',
processors=[ResizeToFill(48, 48)],
format='PNG',
options={'quality': 90}, null=True, blank=True)
image_k_txt = models.CharField(max_length=254, verbose_name='Küçük Resim Yazisi', null=True)
is_active = models.BooleanField(default=True, verbose_name='Yayındamı ?', choices=aktif)
created_at = models.DateTimeField(auto_now_add=True, editable=False, verbose_name="Oluşturulma Tarihi")
updated_at = models.DateTimeField(auto_now=True, editable=False, verbose_name="Güncelleme Tarihi")
class Meta:
ordering = ["-created_at"]
db_table = 'banners'
verbose_name_plural = "Bannerler"
verbose_name = "Banner"
def __str__(self):
return str(self.title)
class SiteSettings(models.Model):
aktif = (
(True, 'Evet'),
(False, 'Hayır'),
)
is_active = models.BooleanField(default=True, verbose_name='Yayındamı ?', choices=aktif)
site_active = models.BooleanField(default=True, verbose_name='Site Aktifmi ?', choices=aktif)
created_at = models.DateTimeField(auto_now_add=True, editable=False, verbose_name="Oluşturulma Tarihi")
updated_at = models.DateTimeField(auto_now=True, editable=False, verbose_name="Güncelleme Tarihi")
class Meta:
ordering = ["-created_at"]
db_table = 'site_settings'
verbose_name_plural = "Site Ayarları Aç / Kapat"
verbose_name = "Site Ayarı Aç / Kapat"
def __str__(self):
return f"Site Ayarı {self.pk}"

101
settings/serializers.py Normal file
View File

@@ -0,0 +1,101 @@
from rest_framework import serializers
from django.conf import settings
# from product.models import Category, Product, Images, Tags
from settings.models import Setting, SiteSettings
"""
title
content
categories
keywords
brim
price
tags
gallery
images
thumb
video
slug
created_at
updated_at
is_active
is_front
"""
"""
class CateSerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ['title', 'parent', 'is_active', 'created_at', 'order', 'slug', 'images', 'keywords', 'description']
class GalSerializer(serializers.ModelSerializer):
class Meta:
model = Images
fields = ['title', 'images']
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tags
fields = ['tag', 'slug']
class ProductSerializer(serializers.ModelSerializer):
categories = CateSerializer(read_only=True, many=True)
gallery = GalSerializer(read_only=True, many=True)
tags = TagSerializer(read_only=True, many=True)
class Meta:
model = Product
fields = ['title', 'content', 'categories', 'keywords', 'brim', 'tags', 'gallery', 'images', 'thumb', 'video',
'slug', 'created_at', 'updated_at', 'is_active', 'is_front','price']
# fields = '__all__'
class CategorySerializer(serializers.ModelSerializer):
categories = ProductSerializer(read_only=True, many=True)
child = serializers.SerializerMethodField()
class Meta:
model = Category
fields = ['title', 'parent', 'is_active', 'created_at', 'order', 'slug', 'images', 'keywords', 'description',
'categories', 'child']
def get_child(self, obj):
serializer = self.__class__(obj.child.all(), many=True, context=self.context)
return serializer.data
"""
class SettingSerializer(serializers.ModelSerializer):
b_logo = serializers.SerializerMethodField()
w_logo = serializers.SerializerMethodField()
class Meta:
model = Setting
fields = ['title', 'meta_title', 'meta_description', 'phone', 'url', 'email', 'facebook', 'x','pinterest','linkedin',
'instagram', 'whatsapp', 'slogan', 'w_logo', 'b_logo', 'created_at',
'updated_at', 'is_active']
def get_w_logo(self, obj):
if obj.w_logo:
# Sadece path döndür, domain olmadan
return obj.w_logo.url
return None
def get_b_logo(self, obj):
if obj.b_logo:
# Sadece path döndür, domain olmadan
return obj.b_logo.url
return None
class SettingOpenCloseSerializer(serializers.ModelSerializer):
class Meta:
model = SiteSettings
fields = ['is_active','site_active']

17
settings/signals.py Normal file
View File

@@ -0,0 +1,17 @@
from django.core.cache import cache
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from settings.models import Setting, SiteSettings
def clear_all_cache():
cache.clear()
@receiver(post_save, sender=Setting)
@receiver(post_delete, sender=Setting)
@receiver(post_save, sender=SiteSettings)
@receiver(post_delete, sender=SiteSettings)
def clear_settings_cache_on_change(sender, instance, **kwargs):
clear_all_cache()

3
settings/tests.py Normal file
View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

8
settings/urls.py Normal file
View File

@@ -0,0 +1,8 @@
from django.urls import path, include
from .views import SettingDetailView, SettingOpenCloseDetailView
urlpatterns = [ # Success/Error pages
path('settings/', SettingDetailView.as_view(), name='settings'),
path('open-close/', SettingOpenCloseDetailView.as_view(), name='open.close'),
]

55
settings/views.py Normal file
View File

@@ -0,0 +1,55 @@
from django.core.cache import cache
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from core.Permission import ReadOnly
from settings.models import Setting, SiteSettings
from settings.serializers import SettingSerializer, SettingOpenCloseSerializer
CACHE_TTL_SECONDS = 60 * 5
# Create your views here.
class SettingDetailView(APIView):
permission_classes = [ReadOnly]
def get(self, request):
try:
cache_key = 'settings:detail'
cached_data = cache.get(cache_key)
if cached_data:
return Response(cached_data)
# İlk kaydı getir (veya istediğin koşula göre)
setting = Setting.objects.filter(is_active=True).first()
if setting:
serializer = SettingSerializer(setting)
cache.set(cache_key, serializer.data, timeout=CACHE_TTL_SECONDS)
return Response(serializer.data)
else:
return Response({"error": "No settings found"}, status=status.HTTP_404_NOT_FOUND)
except Exception as e:
return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class SettingOpenCloseDetailView(APIView):
permission_classes = [ReadOnly]
def get(self, request):
try:
cache_key = 'settings:site_status'
cached_data = cache.get(cache_key)
if cached_data:
return Response(cached_data)
# İlk kaydı getir (veya istediğin koşula göre)
setting = SiteSettings.objects.filter(is_active=True).first()
if setting:
serializer = SettingOpenCloseSerializer(setting)
cache.set(cache_key, serializer.data, timeout=CACHE_TTL_SECONDS)
return Response(serializer.data)
else:
return Response({"error": "No settings found"}, status=status.HTTP_404_NOT_FOUND)
except Exception as e:
return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)