diff --git a/.gitignore b/.gitignore index ab3e8ce..a570204 100644 --- a/.gitignore +++ b/.gitignore @@ -162,3 +162,4 @@ cython_debug/ # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ +uploads diff --git a/cms/settings.py b/cms/settings.py index bf1e1a0..664e406 100644 --- a/cms/settings.py +++ b/cms/settings.py @@ -5,6 +5,7 @@ DEBUG = True ALLOWED_HOSTS = [] INSTALLED_APPS = [ 'unfold', + 'unfold.contrib.forms', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -64,4 +65,6 @@ TIME_ZONE = 'Europe/Moscow' USE_I18N = True USE_TZ = True STATIC_URL = 'static/' -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' \ No newline at end of file +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +MEDIA_URL = "/media/" +MEDIA_ROOT = BASE_DIR / "uploads" \ No newline at end of file diff --git a/cmsMain/admin.py b/cmsMain/admin.py index 82220f3..e04769e 100644 --- a/cmsMain/admin.py +++ b/cmsMain/admin.py @@ -2,7 +2,9 @@ from django.contrib import admin from django.contrib.auth.admin import UserAdmin,GroupAdmin from django.contrib.auth.models import User, Group from unfold.admin import ModelAdmin -from .models import Site, Page, Url, Variable +from .models import Site, Page, Url, Variable, File, Post, Feedback +from unfold.contrib.forms.widgets import WysiwygWidget +from django.db import models admin.site.unregister(Group) admin.site.unregister(User) @@ -19,6 +21,11 @@ class SiteAdmin(ModelAdmin): @admin.register(Page) class PageAdmin(ModelAdmin): pass + # formfield_overrides = { + # models.TextField: { + # "widget": WysiwygWidget + # } + # } @admin.register(Url) class UrlAdmin(ModelAdmin): @@ -29,4 +36,20 @@ class UrlAdmin(ModelAdmin): @admin.register(Variable) class VariableAdmin(ModelAdmin): list_display = ["name","value"] - list_editable = ["value"] \ No newline at end of file + list_editable = ["value"] + +@admin.register(File) +class FileAdmin(ModelAdmin): pass + +@admin.register(Post) +class PostAdmin(ModelAdmin): + list_display = ["author","title"] + list_display_links = ["author","title"] + def save_model(self,request,obj,form,change): + obj.author = request.user + obj.save() + +@admin.register(Feedback) +class FeedbackAdmin(ModelAdmin): + list_display = ["name","email"] + list_display_links = ["name","email"] diff --git a/cmsMain/migrations/0005_feedback_file_post.py b/cmsMain/migrations/0005_feedback_file_post.py new file mode 100644 index 0000000..376a802 --- /dev/null +++ b/cmsMain/migrations/0005_feedback_file_post.py @@ -0,0 +1,55 @@ +# Generated by Django 5.1 on 2024-08-21 13:20 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cmsMain', '0004_variable'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Feedback', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('email', models.EmailField(max_length=254, verbose_name='Почта')), + ('name', models.CharField(max_length=50, verbose_name='Имя')), + ('message', models.TextField(verbose_name='Сообщение')), + ], + options={ + 'verbose_name': 'Обращение', + 'verbose_name_plural': 'Обращения', + }, + ), + migrations.CreateModel( + name='File', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=50, verbose_name='Имя')), + ('value', models.FileField(upload_to='files', verbose_name='Значение')), + ], + options={ + 'verbose_name': 'Файл', + 'verbose_name_plural': 'Файлы', + }, + ), + migrations.CreateModel( + name='Post', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=100, verbose_name='Название')), + ('content', models.TextField(verbose_name='Содержимое')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('author', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL, verbose_name='Автор')), + ], + options={ + 'verbose_name': 'Пост', + 'verbose_name_plural': 'Посты', + }, + ), + ] diff --git a/cmsMain/migrations/0006_post_url.py b/cmsMain/migrations/0006_post_url.py new file mode 100644 index 0000000..cee604f --- /dev/null +++ b/cmsMain/migrations/0006_post_url.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1 on 2024-09-01 10:16 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cmsMain', '0005_feedback_file_post'), + ] + + operations = [ + migrations.AddField( + model_name='post', + name='url', + field=models.CharField(default='/test-post', help_text='Без слеша в начале, например: blog/test-post или my-first-test-post', max_length=100, verbose_name='Ссылка'), + preserve_default=False, + ), + ] diff --git a/cmsMain/models.py b/cmsMain/models.py index edd688b..23a7cf1 100644 --- a/cmsMain/models.py +++ b/cmsMain/models.py @@ -1,5 +1,5 @@ from django.db import models - +from django.contrib.auth.models import User # Create your models here. class Page(models.Model): @@ -37,4 +37,36 @@ class Variable(models.Model): return self.name class Meta: verbose_name = "Переменная" - verbose_name_plural = "Переменные" \ No newline at end of file + verbose_name_plural = "Переменные" + +class File(models.Model): + name = models.CharField("Имя",max_length=50) + value = models.FileField("Значение",upload_to="files") + def __str__(self): + return self.name + class Meta: + verbose_name = "Файл" + verbose_name_plural = "Файлы" + +class Post(models.Model): + url = models.CharField("Ссылка",help_text="например: my-first-test-post",max_length=100) + title = models.CharField("Название",max_length=100) + author = models.ForeignKey(User,editable=False,verbose_name="Автор",on_delete=models.PROTECT) + content = models.TextField("Содержимое") + created_at = models.DateTimeField(auto_now_add=True) + def __str__(self): + return f"{self.title} by {self.author.username}" + class Meta: + verbose_name = "Пост" + verbose_name_plural = "Посты" + +class Feedback(models.Model): + email = models.EmailField("Почта") + name = models.CharField("Имя",max_length=50) + message = models.TextField("Сообщение") + def __str__(self): + return f"{self.name} | {self.name}" + class Meta: + verbose_name = "Обращение" + verbose_name_plural = "Обращения" + \ No newline at end of file diff --git a/cmsMain/templatetags/cms_tags.py b/cmsMain/templatetags/cms_tags.py index bf9535e..802bc55 100644 --- a/cmsMain/templatetags/cms_tags.py +++ b/cmsMain/templatetags/cms_tags.py @@ -1,8 +1,13 @@ from django import template -from ..models import Variable +from ..models import Variable, File register = template.Library() @register.simple_tag def var(name): v = Variable.objects.get(name=name) - if v: return v.value \ No newline at end of file + if v: return v.value + +@register.simple_tag +def file(name): + f = File.objects.get(name=name) + if f: return f.value.url \ No newline at end of file diff --git a/cmsMain/tests.py b/cmsMain/tests.py deleted file mode 100644 index 7ce503c..0000000 --- a/cmsMain/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/cmsMain/urls.py b/cmsMain/urls.py index 9703366..aecc6e5 100644 --- a/cmsMain/urls.py +++ b/cmsMain/urls.py @@ -1,7 +1,10 @@ from django.urls import path, include from .views import MainView, PageView - +from django.conf.urls.static import static +from django.conf import settings urlpatterns = [ +*static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT), path('',PageView.as_view()), path('',MainView.as_view()) -] \ No newline at end of file +] + diff --git a/cmsMain/views.py b/cmsMain/views.py index d97633c..4259b39 100644 --- a/cmsMain/views.py +++ b/cmsMain/views.py @@ -1,7 +1,7 @@ from django.shortcuts import render, get_object_or_404 from django.views import View from django import template -from .models import Site, Url, Variable +from .models import Site, Url, Variable, Post from django.http import HttpResponse context = template.Context({}) @@ -12,12 +12,20 @@ class MainView(View): class PageView(View): def get(self,request,page): s = get_object_or_404(Site,domain=request.META["HTTP_HOST"]) + r = Url.objects.filter(path=page,site=s) + post = None + if "post" in request.GET: + post = Post.objects.filter(url=request.GET["post"]) + if post: post = post.first() r = get_object_or_404(Url,path=page,site=s) t = template.Template(r.page.content) content = t.render(context) context.update({ "content": content, - "title": r.page.title + "title": r.page.title, + "url": page, + "posts": Post.objects.all(), + "post": post }) t = template.Template(s.base_page.content) return HttpResponse(t.render(context)) \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..9d364ae --- /dev/null +++ b/index.html @@ -0,0 +1,79 @@ + + + + + + doesnm/cms + + +
+
+ Главная + Блог + Обратная связь +
+
+
+

Блог

+
+

Система управления контентом написанная на Django имеющая возможность вести свой блог и принимать обратную связь от пользователей

+ +

Статистика:

+

Количество пользователей: 0

+

Количество обращений: 0

+

Количество постов: 0

+
+ Перейти в админку +
+ + + \ No newline at end of file diff --git a/logo.svg b/logo.svg new file mode 100644 index 0000000..4b2523b --- /dev/null +++ b/logo.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + +