Commit 8592d5b4 authored by Давид Ли's avatar Давид Ли

lesson 49

parent e48eda9f
......@@ -21,11 +21,12 @@ from web import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index_view, name='main-page'),
path('', views.MainPageRedirectView.as_view()),
path('articles/', views.index_view, name='main_page'),
path('articles/add/', views.ArticleCreateView.as_view(), name='articles-add'),
# /articles/1/ OR /articles/?id=1
# article_details_view(request, id)
path('articles/<int:id>/', views.article_detail_view, name='articles-detail'),
path('articles/<int:id>/', views.ArticleDetailView.as_view(), name='articles-detail'),
path('articles/<int:id>/edit', views.article_update_view, name='article_update'),
path('articles/<int:id>/delete', views.delete_article, name='delete_article')
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# Generated by Django 3.2.19 on 2023-07-10 10:25
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('web', '0005_alter_article_status'),
]
operations = [
migrations.CreateModel(
name='Comment',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('text', models.TextField(max_length=400, verbose_name='Текст')),
('author', models.CharField(blank=True, default='Аноним', max_length=40, null=True, verbose_name='Автор')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Время создания')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Время обновления')),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='web.article', verbose_name='Статья')),
],
options={
'verbose_name': 'Комментарий',
'verbose_name_plural': 'Комментарии',
},
),
]
# Generated by Django 3.2.19 on 2023-07-10 11:41
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('web', '0006_comment'),
]
operations = [
migrations.CreateModel(
name='Tag',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=30, verbose_name='Тег')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Время создания')),
],
),
migrations.CreateModel(
name='ArticleTag',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.article', verbose_name='Статья')),
('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='articles', to='web.tag', verbose_name='Тег')),
],
options={
'db_table': 'article_tag',
},
),
migrations.AddField(
model_name='article',
name='tags',
field=models.ManyToManyField(blank=True, through='web.ArticleTag', to='web.Tag'),
),
]
# Generated by Django 3.2.19 on 2023-07-10 12:10
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('web', '0007_auto_20230710_1741'),
]
operations = [
migrations.RenameField(
model_name='article',
old_name='tags',
new_name='tags_old',
),
]
# Generated by Django 3.2.19 on 2023-07-10 12:13
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('web', '0008_rename_tags_article_tags_old'),
]
operations = [
migrations.AddField(
model_name='article',
name='tags',
field=models.ManyToManyField(blank=True, related_name='articles', to='web.Tag'),
),
migrations.AlterField(
model_name='articletag',
name='tag',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='articles_set', to='web.tag', verbose_name='Тег'),
),
]
# Generated by Django 3.2.19 on 2023-07-10 12:14
from django.db import migrations
def transfer_tags(apps, schema_editor):
Article = apps.get_model('web.Article')
for article in Article.objects.all():
article.tags.set(article.tags_old.all())
def rollback_transfer(apps, schema_editor):
Article = apps.get_model('web.Article')
for article in Article.objects.all():
article.tags_old.set(article.tags.all())
class Migration(migrations.Migration):
dependencies = [
('web', '0009_auto_20230710_1813'),
]
operations = [
migrations.RunPython(transfer_tags, rollback_transfer)
]
# Generated by Django 3.2.19 on 2023-07-10 12:18
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('web', '0010_auto_20230710_1814'),
]
operations = [
migrations.RemoveField(
model_name='article',
name='tags_old',
),
migrations.DeleteModel(
name='ArticleTag',
),
]
from web.models.article import Article, StatusChoices
from web.models.comment import Comment
from web.models.tag import Tag
......@@ -18,6 +18,8 @@ class Article(models.Model):
verbose_name='Заголовок'
)
tags = models.ManyToManyField('web.Tag', related_name='articles', blank=True)
# accepted, check, unaccepted
status = models.CharField(
max_length=100,
......
from django.db import models
# article_1 - (comment_1, comment_2)
# comment_1 = comment_1.article
# comment_1 = comment_1.article_id
# article_1 = article_1.comment.all()
class Comment(models.Model):
# article - object
# article_id - id
article = models.ForeignKey(
'web.Article',
on_delete=models.CASCADE,
related_name='comments',
verbose_name='Статья'
)
text = models.TextField(max_length=400, verbose_name='Текст')
author = models.CharField(
max_length=40,
null=True,
blank=True,
default='Аноним',
verbose_name='Автор'
)
created_at = models.DateTimeField(
auto_now_add=True,
verbose_name='Время создания'
)
updated_at = models.DateTimeField(
auto_now=True,
verbose_name='Время обновления'
)
class Meta:
verbose_name = 'Комментарий'
verbose_name_plural = 'Комментарии'
def __str__(self):
return f'{self.article.title}: {self.author} | {self.text[:30]}...'
from django.db import models
class Tag(models.Model):
name = models.CharField(max_length=30, verbose_name='Тег')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='Время создания')
def __str__(self):
return self.name
......@@ -13,7 +13,7 @@
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<a class="navbar-brand" href="{% url 'main-page' %}">Articles</a>
<a class="navbar-brand" href="{% url 'main_page' %}">Articles</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
......
from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse
from django.views import View
from django.views.generic import View, TemplateView, RedirectView
from web.forms import ArticleForm
from web.models import Article, StatusChoices
......@@ -14,6 +14,10 @@ def index_view(request):
)
class MainPageRedirectView(RedirectView):
pattern_name = 'main_page'
# Class-based views
class ArticleCreateView(View):
def get(self, request, *args, **kwargs):
......@@ -44,73 +48,19 @@ class ArticleCreateView(View):
return render(self.request, 'article_create.html', context={'form': form, 'status_choices': StatusChoices.choices})
# title = request.POST.get('title')
# if not title:
# errors['title'] = 'Title should not be empty!'
# elif len(title) > 200:
# errors['title'] = 'Title should be 200 symbols or less'
# author = request.POST.get('author')
# if not author:
# errors['author'] = 'Author should not be empty!'
# elif len(author) > 40:
# errors['author'] = 'Author should be 40 symbols or less'
# text = request.POST.get('text')
# if not text:
# errors['text'] = 'Text should not be empty!'
# elif len(text) > 3000:
# errors['text'] = 'Text should be 3000 symbols or less'
# status = request.POST.get('status')
# if not status:
# errors['status'] = 'Status should not be empty!'
# if len(errors) > 0:
# article_not_saved = Article(title=title, status=status, text=text, author=author)
# return render(self.request,
# 'article_create.html',
# context={
# 'status_choices': StatusChoices.choices,
# 'errors': errors,
# 'article': article_not_saved
# })
article = Article.objects.create(title=title, author=author, status=status, text=text)
return redirect('articles-detail', id=article.id)
# def article_create_view(request):
# if request.method == 'GET':
# return render(
# request,
# 'article_create.html',
# context={
# 'status_choices': StatusChoices.choices
# }
# )
#
# elif request.method == 'POST':
# data = request.POST
# article_data = {
# 'title': data.get('title'),
# 'text': data.get('text'),
# 'author': data.get('author'),
# 'status': data.get('status')
# }
#
# article = Article.objects.create(**article_data)
#
# return redirect('articles-detail', id=article.id)
# /articles/{id}
def article_detail_view(request, id: int):
article = get_object_or_404(Article, id=id)
return render(request, 'article.html', context={'article': article})
class ArticleDetailView(TemplateView):
template_name = 'article.html'
def get_context_data(self, **kwargs):
article = get_object_or_404(Article, id=kwargs.get('id'))
return super().get_context_data(article=article)
def article_update_view(request, id):
article = get_object_or_404(Article, pk=id)
if request.method == 'GET':
......@@ -132,7 +82,7 @@ def article_update_view(request, id):
article.save()
return redirect('articles-detail', id=article.pk)
else:
return render(request, 'update.html', context={'article': article, 'form': form, 'status_choices': StatusChoices.choices}))
return render(request, 'update.html', context={'article': article, 'form': form, 'status_choices': StatusChoices.choices})
def delete_article(request, id):
......@@ -142,4 +92,4 @@ def delete_article(request, id):
elif request.method == 'POST':
article.delete()
return redirect('main-page')
return redirect('main_page')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment