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

lesson 49

parent e48eda9f
...@@ -21,11 +21,12 @@ from web import views ...@@ -21,11 +21,12 @@ from web import views
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), 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'), path('articles/add/', views.ArticleCreateView.as_view(), name='articles-add'),
# /articles/1/ OR /articles/?id=1 # /articles/1/ OR /articles/?id=1
# article_details_view(request, id) # 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>/edit', views.article_update_view, name='article_update'),
path('articles/<int:id>/delete', views.delete_article, name='delete_article') path('articles/<int:id>/delete', views.delete_article, name='delete_article')
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) ] + 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): ...@@ -18,6 +18,8 @@ class Article(models.Model):
verbose_name='Заголовок' verbose_name='Заголовок'
) )
tags = models.ManyToManyField('web.Tag', related_name='articles', blank=True)
# accepted, check, unaccepted # accepted, check, unaccepted
status = models.CharField( status = models.CharField(
max_length=100, 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 @@ ...@@ -13,7 +13,7 @@
<body> <body>
<nav class="navbar navbar-expand-lg navbar-light bg-light"> <nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container"> <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"> <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> <span class="navbar-toggler-icon"></span>
</button> </button>
......
from django.shortcuts import render, redirect, get_object_or_404 from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse 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.forms import ArticleForm
from web.models import Article, StatusChoices from web.models import Article, StatusChoices
...@@ -14,6 +14,10 @@ def index_view(request): ...@@ -14,6 +14,10 @@ def index_view(request):
) )
class MainPageRedirectView(RedirectView):
pattern_name = 'main_page'
# Class-based views # Class-based views
class ArticleCreateView(View): class ArticleCreateView(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
...@@ -44,73 +48,19 @@ class ArticleCreateView(View): ...@@ -44,73 +48,19 @@ class ArticleCreateView(View):
return render(self.request, 'article_create.html', context={'form': form, 'status_choices': StatusChoices.choices}) 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} # /articles/{id}
def article_detail_view(request, id: int): def article_detail_view(request, id: int):
article = get_object_or_404(Article, id=id) article = get_object_or_404(Article, id=id)
return render(request, 'article.html', context={'article': article}) 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): def article_update_view(request, id):
article = get_object_or_404(Article, pk=id) article = get_object_or_404(Article, pk=id)
if request.method == 'GET': if request.method == 'GET':
...@@ -132,7 +82,7 @@ def article_update_view(request, id): ...@@ -132,7 +82,7 @@ def article_update_view(request, id):
article.save() article.save()
return redirect('articles-detail', id=article.pk) return redirect('articles-detail', id=article.pk)
else: 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): def delete_article(request, id):
...@@ -142,4 +92,4 @@ def delete_article(request, id): ...@@ -142,4 +92,4 @@ def delete_article(request, id):
elif request.method == 'POST': elif request.method == 'POST':
article.delete() 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