Skip to content

Commit 8db86fa

Browse files
committed
Update django comments
1 parent 5c38de0 commit 8db86fa

File tree

19 files changed

+239
-42
lines changed

19 files changed

+239
-42
lines changed

django-comments/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,28 @@ $ python manage.py runserver
3333
```
3434

3535
Then visit [`http://127.0.0.1:8000`](http://127.0.0.1:8000)
36+
37+
38+
## Create a Superuser
39+
40+
```bash
41+
$ python manage.py createsuperuser
42+
```
43+
44+
Then you can manage the data via Django admin panel - [`http://127.0.0.1:8000/admin`](http://127.0.0.1:8000/admin)
45+
46+
47+
48+
## Run Django Migration
49+
50+
Make the migration files,
51+
52+
```bash
53+
$ python3 manage.py makemigrations
54+
```
55+
56+
Migrate the models,
57+
58+
```bash
59+
$ python3 migrate.py migrate
60+
```

django-comments/articles/admin.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
from django.contrib import admin
22

3+
from articles.models import Article
4+
35
# Register your models here.
6+
@admin.register(Article)
7+
class ArticleAdmin(admin.ModelAdmin):
8+
list_display = ['title', 'content', 'author', 'created_at', 'updated_at']
9+
search_fields = ['title', 'content']
10+
readonly_fields = ['created_at']
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Generated by Django 5.0.6 on 2024-05-22 12:36
2+
3+
import django.db.models.deletion
4+
from django.conf import settings
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
initial = True
11+
12+
dependencies = [
13+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14+
]
15+
16+
operations = [
17+
migrations.CreateModel(
18+
name='Article',
19+
fields=[
20+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
21+
('title', models.CharField(max_length=200, verbose_name='Title')),
22+
('content', models.TextField(blank=True, null=True, verbose_name='Content')),
23+
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')),
24+
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')),
25+
('author', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='articles', to=settings.AUTH_USER_MODEL)),
26+
],
27+
options={
28+
'verbose_name': 'Article',
29+
'verbose_name_plural': 'Article',
30+
'db_table': 'articles',
31+
},
32+
),
33+
]

django-comments/articles/models.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
from django.contrib.contenttypes.fields import GenericRelation
2+
from django.contrib.auth.models import User
13
from django.db import models
24

5+
from comments.models import Comment
6+
7+
38
# Create your models here.
9+
class Article(models.Model):
10+
title = models.CharField(verbose_name='Title', max_length=200)
11+
content = models.TextField(verbose_name='Content', blank=True, null=True)
12+
author = models.ForeignKey(User, related_name='articles', on_delete=models.SET_NULL, null=True)
13+
created_at = models.DateTimeField(verbose_name='Created At', auto_now_add=True, editable=False)
14+
updated_at = models.DateTimeField(verbose_name='Updated At', auto_now=True)
15+
16+
# Add comment to this model
17+
comments = GenericRelation(Comment)
18+
19+
class Meta:
20+
verbose_name = 'Article'
21+
verbose_name_plural = 'Article'
22+
db_table = 'articles'

django-comments/articles/templates/base.html

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@
22

33
<!DOCTYPE html>
44
<html lang="en">
5+
56
<head>
67
<meta charset="UTF-8">
78
<meta name="viewport" content="width=device-width, initial-scale=1.0">
9+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"
10+
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
811
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
912
<title>{% block title %}{% endblock %}</title>
1013
</head>
14+
1115
<body>
12-
{% include 'header.html' %}
13-
{% block content %}
14-
{% endblock %}
16+
{% block content %}{% endblock %}
17+
18+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js" integrity="sha384-BBtl+eGJRgqQAUMxJ7pMwbEyER4l1g+O15P+16Ep7Q9Q+zqX6gSbd85u4mG4QzX+" crossorigin="anonymous"></script>
1519
</body>
16-
</html>
20+
21+
</html>

django-comments/articles/templates/header.html

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,44 @@
11
{% extends "base.html" %}
22
{% load static %}
33

4+
{% load crispy_forms_tags %}
5+
6+
47
{% block title %} Django & Comments {% endblock %}
58

69
{% block content %}
7-
<h1 class="text-center">Django & Comments Example</h1>
8-
<p class="m-4 text-red-400 text-center">Hello, this is an example Django project with Comments.</p>
10+
<div class="container">
11+
<h1 class="text-center mt-5">Django & Comments - TinyMCE</h1>
12+
<p class="m-4 text-center">Hello, this is an example Django project with Comments.</p>
13+
14+
<hr />
15+
<div class="row">
16+
<h2 class="p-20 text-center">{{article.title}} 😁</h2>
17+
<p>{{article.content}}</p>
18+
</div>
919

20+
<hr />
21+
{% for comment in comments %}
22+
<div class="row">
23+
<div class="col-12">
24+
<div class="card mb-2">
25+
<div class="card-body">
26+
<p><span>{{comment.user}} @ {{comment.creation_date}}</span></p>
27+
<p class="card-text mt-3">{{ comment.content | safe }}</p>
28+
</div>
29+
</div>
30+
</div>
31+
</div>
32+
{% endfor %}
33+
<hr />
1034

11-
<h2 class="p-20 text-4xl text-center text-green-500">A simple page using TinyMCE!</h2>
12-
<h3 class="text-2xl text-center text-purple-700">Very impressive 😁</h3>
35+
<div class="row">
36+
<div class="col-12 mt-5 mb-5">
37+
<form method="POST" class="form-horizontal" autocomplete="off">
38+
{% csrf_token %}
39+
{% crispy form %}
40+
</form>
41+
</div>
42+
</div>
43+
</div>
1344
{% endblock %}

django-comments/articles/views.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,33 @@
1-
from django.shortcuts import render
1+
from django.contrib.auth.models import User
2+
from django.shortcuts import render, redirect
3+
from django.views.generic import View
4+
5+
from articles.models import Article
6+
from comments.forms import CommentForm
7+
from comments.models import Comment
8+
29

310
# Create your views here.
4-
def index(request):
5-
return render(request, "index.html")
11+
class ArticleView(View):
12+
13+
def get(self, request, *args, **kwargs):
14+
article = Article.objects.first()
15+
form = CommentForm()
16+
comments = Comment.objects.all()
17+
context = {'article': article, 'form': form, 'comments': comments}
18+
19+
return render(request, "index.html", context=context)
20+
21+
def post(self, request, *args, **kwargs):
22+
article = Article.objects.first()
23+
form = CommentForm(request.POST)
24+
25+
# Random get a user
26+
user = User.objects.first()
27+
28+
if form.is_valid():
29+
comment = form.save(commit=False)
30+
comment.user = user
31+
comment.content_object = article
32+
comment.save()
33+
return redirect('index')

django-comments/comments/admin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from django.contrib import admin
22

3-
from comments import Comment
3+
from comments.models import Comment
44

55
# Register your models here.
66
@admin.register(Comment)

django-comments/comments/forms.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from crispy_forms.layout import ButtonHolder, Column, Layout, Row, Submit
66
from tinymce.widgets import TinyMCE
77

8-
from comments import Comment
8+
from comments.models import Comment
99

1010

1111
CUSTOM_MCE_ATTRS = {
@@ -23,7 +23,7 @@
2323

2424

2525
class CommentForm(forms.ModelForm):
26-
content = forms.CharField(label='New Comment', widget=TinyMCE(mce_attrs=CUSTOM_MCE_ATTRS))
26+
content = forms.CharField(label='Comment', widget=TinyMCE(mce_attrs=CUSTOM_MCE_ATTRS))
2727

2828
class Meta:
2929
model = Comment
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Generated by Django 5.0.6 on 2024-05-22 12:31
2+
3+
import django.db.models.deletion
4+
import django.utils.timezone
5+
import tinymce.models
6+
from django.conf import settings
7+
from django.db import migrations, models
8+
9+
10+
class Migration(migrations.Migration):
11+
12+
initial = True
13+
14+
dependencies = [
15+
('contenttypes', '0002_remove_content_type_name'),
16+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
17+
]
18+
19+
operations = [
20+
migrations.CreateModel(
21+
name='Comment',
22+
fields=[
23+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
24+
('content', tinymce.models.HTMLField(max_length=512, verbose_name='Content')),
25+
('creation_date', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Date/Time Created')),
26+
('is_removed', models.BooleanField(default=False, verbose_name='Is Removed')),
27+
('object_id', models.PositiveBigIntegerField(db_index=True, verbose_name='Object ID')),
28+
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype', verbose_name='Content-Type')),
29+
('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
30+
],
31+
options={
32+
'verbose_name': 'Comment',
33+
'verbose_name_plural': 'Comments',
34+
'db_table': 'comments',
35+
'ordering': ('creation_date',),
36+
},
37+
),
38+
]

django-comments/comments/models.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ class Comment(models.Model):
2121
class Meta:
2222
verbose_name = 'Comment'
2323
verbose_name_plural = 'Comments'
24-
ordering = ('createion_date')
24+
ordering = ('creation_date',)
25+
db_table = 'comments'

django-comments/djangoconfig/asgi.py renamed to django-comments/config/asgi.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
ASGI config for djangoconfig project.
2+
ASGI config for django-comments project.
33
44
It exposes the ASGI callable as a module-level variable named ``application``.
55
@@ -11,6 +11,6 @@
1111

1212
from django.core.asgi import get_asgi_application
1313

14-
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoconfig.settings')
14+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
1515

1616
application = get_asgi_application()

django-comments/djangoconfig/settings.py renamed to django-comments/config/settings.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Django settings for djangoconfig project.
2+
Django settings for django-comments project.
33
44
Generated by 'django-admin startproject' using Django 5.0.3.
55
@@ -38,6 +38,11 @@
3838
'django.contrib.messages',
3939
'django.contrib.staticfiles',
4040

41+
# Third party libraries
42+
'crispy_forms',
43+
'crispy_bootstrap5',
44+
'tinymce',
45+
4146
# Custom applications
4247
'comments',
4348
'articles'
@@ -53,7 +58,7 @@
5358
'django.middleware.clickjacking.XFrameOptionsMiddleware',
5459
]
5560

56-
ROOT_URLCONF = 'djangoconfig.urls'
61+
ROOT_URLCONF = 'config.urls'
5762

5863
TEMPLATES = [
5964
{
@@ -71,7 +76,7 @@
7176
},
7277
]
7378

74-
WSGI_APPLICATION = 'djangoconfig.wsgi.application'
79+
WSGI_APPLICATION = 'config.wsgi.application'
7580

7681

7782
# Database
@@ -128,3 +133,22 @@
128133
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
129134

130135
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
136+
137+
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
138+
139+
CRISPY_TEMPLATE_PACK = "bootstrap5"
140+
141+
142+
TINYMCE_DEFAULT_CONFIG = {
143+
'selector': 'textarea',
144+
'theme': 'modern',
145+
'plugins': 'link image preview codesample contextmenu table code lists',
146+
'toolbar1': 'formatselect | bold italic underline | alignleft aligncenter alignright alignjustify '
147+
'| bullist numlist | outdent indent | table | link image | codesample | preview code',
148+
'contextmenu': 'formats | link image',
149+
'menubar': False,
150+
'inline': False,
151+
'statusbar': True,
152+
'width': 'auto',
153+
'height': 360,
154+
}

django-comments/djangoconfig/urls.py renamed to django-comments/config/urls.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
URL configuration for djangoconfig project.
2+
URL configuration for django-comments project.
33
44
The `urlpatterns` list routes URLs to views. For more information please see:
55
https://docs.djangoproject.com/en/5.0/topics/http/urls/
@@ -17,10 +17,11 @@
1717
from django.contrib import admin
1818
from django.urls import include, path
1919

20-
from articles.views import index
20+
from articles.views import ArticleView
2121

2222

2323
urlpatterns = [
2424
path('admin/', admin.site.urls),
25-
path('', index, name='index'),
25+
path('tinymce/', include('tinymce.urls')),
26+
path('', ArticleView.as_view(), name='index'),
2627
]

0 commit comments

Comments
 (0)