Commmit

parent 41987858
from django.core.exceptions import ValidationError
from django.forms.models import ModelForm
from django.forms import CharField
from articles.models import Article, Author, Comment
def at_least_10(string):
if len(string) < 10:
raise ValidationError("Имя слишком короткое")
class AuthorForm(ModelForm):
name = CharField(max_length=200, required=True, label='Имя автора', validators=(at_least_10,))
class Meta:
model = Author
fields = ("name",)
......@@ -12,3 +22,24 @@ class CommentForm(ModelForm):
class Meta:
model = Comment
fields = ("text", "author")
class ArticleForm(ModelForm):
body = CharField(max_length=200, required=True, label='Текст', validators=(at_least_10,))
def clean(self):
cleaned_data = super().clean()
print(cleaned_data)
if cleaned_data['body'] == cleaned_data['title']:
raise ValidationError('Текст в названии и теле статьи совпадает')
return cleaned_data
def clean_author(self):
author = self.cleaned_data.get('author')
if author.id == 1:
raise ValidationError(f"У автора {author} слишком много статей!")
return author
class Meta:
model = Article
fields = "__all__"
from django.shortcuts import render, redirect
from django.views import View
class CustomFormView(View):
form_class = None
template_name = None
redirect_url = ''
def get(self, request, *args, **kwargs):
form = self.form_class()
context = self.get_context_data(form=form)
return render(request, self.template_name, context=context)
def post(self, request, *args, **kwargs):
form = self.form_class(data=request.POST)
if form.is_valid():
return self.form_valid(form)
return self.form_invalid(form)
def form_valid(self, form):
return redirect(self.get_redirect_url())
def form_invalid(self, form):
context = self.get_context_data(form=form)
return render(self.request, self.template_name, context=context)
def get_redirect_url(self):
return self.redirect_url
def get_context_data(self, **kwargs):
return kwargs
# Generated by Django 3.2.6 on 2021-08-16 11:17
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('articles', '0011_auto_20210812_1522'),
]
operations = [
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, related_name='article_tags', to='articles.article', verbose_name='Статья')),
('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tag_articles', to='articles.tag', verbose_name='Тег')),
],
),
]
# Generated by Django 3.2.6 on 2021-08-19 14:06
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('articles', '0012_articletag'),
]
operations = [
migrations.AddField(
model_name='article',
name='number',
field=models.IntegerField(default=4),
),
]
# Generated by Django 3.2.6 on 2021-08-19 14:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('articles', '0013_article_number'),
]
operations = [
migrations.RemoveField(
model_name='article',
name='number',
),
migrations.AddField(
model_name='article',
name='created_at',
field=models.DateTimeField(auto_now_add=True, null=True),
),
]
# Generated by Django 3.2.6 on 2021-08-19 14:37
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('articles', '0014_auto_20210819_1433'),
]
operations = [
migrations.AlterField(
model_name='article',
name='created_at',
field=models.DateTimeField(auto_now_add=True),
),
]
from django.db import models
from datetime import datetime
class Author(models.Model):
name = models.CharField(max_length=50, null=False, verbose_name="Автор")
......@@ -11,23 +11,21 @@ class Author(models.Model):
class Article(models.Model):
title = models.CharField(max_length=250, null=False)
body = models.CharField(max_length=2000, null=True)
created_at = models.DateTimeField(auto_now_add=True, null=False)
author = models.ForeignKey(
"articles.Author",
on_delete=models.SET_NULL,
null=True, related_name='articles')
tags_old = models.ManyToManyField(
'articles.Tag',
related_name="articles_old",
through='articles.ArticleTag',
through_fields=('article', 'tag'),
blank=True
)
tags = models.ManyToManyField(
'articles.Tag',
related_name="articles",
related_name='articles',
blank=True
)
def __str__(self):
return f"{self.id}. {self.title[:20]}"
class Comment(models.Model):
article = models.ForeignKey(
......@@ -69,3 +67,4 @@ class ArticleTag(models.Model):
def __str__(self):
return f"{self.article} | {self.tag}"
......@@ -20,6 +20,7 @@
{% endfor %}
</tbody>
</table>
<a href="{% url 'article_create' %}">Создать статью</a>
<a href="{% url 'author_create' %}">Создать автора</a>
</div>
{% endblock %}
\ No newline at end of file
{% extends 'base.html' %}
{% block content %}
<form action="{% url 'article_create' %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="create">
</form>
{% endblock %}
\ No newline at end of file
......@@ -26,6 +26,7 @@
class="btn btn-success"
value="Оставить комментарий">
</form>
<a href="{% url 'article_update' article.pk %}">Изменить статью</a>
</div>
</div>
......
{% extends 'base.html' %}
{% block content %}
<form action="{% url 'article_update' article.pk %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="create">
</form>
{% endblock %}
\ No newline at end of file
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="#">Navbar</a>
<a class="navbar-brand" href="{% url 'article_list' %}">Navbar</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>
......
......@@ -2,7 +2,7 @@ from django.urls import path
from .views import (
article_list_view,
ArticleDetailView, CommentView,
author_list_view, author_edit_view, author_delete_view, AuthorView
author_list_view, author_edit_view, author_delete_view, AuthorView, CreateArticleView, ArticleUpdateView
)
urlpatterns = [
......@@ -21,7 +21,16 @@ urlpatterns = [
CommentView.as_view(),
name="add_comment"
),
path(
'article/create/',
CreateArticleView.as_view(),
name='article_create'
),
path(
'article/<int:pk>/update',
ArticleUpdateView.as_view(),
name='article_update'
),
path(
'create/',
AuthorView.as_view(),
......
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 FormView
from .helpers.views import CustomFormView
from articles.models import Article, Author
from .forms import AuthorForm, CommentForm
from .forms import AuthorForm, CommentForm, ArticleForm
def article_list_view(request):
......@@ -25,6 +28,62 @@ def author_list_view(request):
)
class CreateArticleView(CustomFormView):
template_name = 'articles/create.html'
form_class = ArticleForm
def form_valid(self, form):
data = {}
tags = form.cleaned_data.pop('tags')
for key, value in form.cleaned_data.items():
if value is not None:
data[key] = value
self.article = Article.objects.create(**data)
self.article.tags.set(tags)
return super().form_valid(form)
def get_redirect_url(self):
return reverse('article_list')
class ArticleUpdateView(FormView):
template_name = "articles/update.html"
form_class = ArticleForm
def dispatch(self, request, *args, **kwargs):
self.article = self.get_object()
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['article'] = self.article
return context
def get_initial(self):
initial = {}
for key in 'title', 'body', 'author', 'tags':
initial[key] = getattr(self.article, key)
initial['tags'] = self.article.tags.all()
return initial
def form_valid(self, form):
tags = form.cleaned_data.pop('tags')
for key, value in form.cleaned_data.items():
if value is not None:
setattr(self.article, key, value)
self.article.save()
self.article.tags.set(tags)
return super().form_valid(form=form)
def get_success_url(self):
return reverse('article_detail', kwargs={'pk': self.article.pk})
def get_object(self):
pk = self.kwargs.get('pk')
return get_object_or_404(Article, pk=pk)
class AuthorView(View):
url_pattern = 'authors/author_create.html'
......
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