Commmit

parent 41987858
from django.core.exceptions import ValidationError
from django.forms.models import ModelForm from django.forms.models import ModelForm
from django.forms import CharField
from articles.models import Article, Author, Comment from articles.models import Article, Author, Comment
def at_least_10(string):
if len(string) < 10:
raise ValidationError("Имя слишком короткое")
class AuthorForm(ModelForm): class AuthorForm(ModelForm):
name = CharField(max_length=200, required=True, label='Имя автора', validators=(at_least_10,))
class Meta: class Meta:
model = Author model = Author
fields = ("name",) fields = ("name",)
...@@ -12,3 +22,24 @@ class CommentForm(ModelForm): ...@@ -12,3 +22,24 @@ class CommentForm(ModelForm):
class Meta: class Meta:
model = Comment model = Comment
fields = ("text", "author") 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 django.db import models
from datetime import datetime
class Author(models.Model): class Author(models.Model):
name = models.CharField(max_length=50, null=False, verbose_name="Автор") name = models.CharField(max_length=50, null=False, verbose_name="Автор")
...@@ -11,23 +11,21 @@ class Author(models.Model): ...@@ -11,23 +11,21 @@ class Author(models.Model):
class Article(models.Model): class Article(models.Model):
title = models.CharField(max_length=250, null=False) title = models.CharField(max_length=250, null=False)
body = models.CharField(max_length=2000, null=True) body = models.CharField(max_length=2000, null=True)
created_at = models.DateTimeField(auto_now_add=True, null=False)
author = models.ForeignKey( author = models.ForeignKey(
"articles.Author", "articles.Author",
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
null=True, related_name='articles') 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( tags = models.ManyToManyField(
'articles.Tag', 'articles.Tag',
related_name="articles", related_name='articles',
blank=True blank=True
) )
def __str__(self):
return f"{self.id}. {self.title[:20]}"
class Comment(models.Model): class Comment(models.Model):
article = models.ForeignKey( article = models.ForeignKey(
...@@ -69,3 +67,4 @@ class ArticleTag(models.Model): ...@@ -69,3 +67,4 @@ class ArticleTag(models.Model):
def __str__(self): def __str__(self):
return f"{self.article} | {self.tag}" return f"{self.article} | {self.tag}"
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<a href="{% url 'article_create' %}">Создать статью</a>
<a href="{% url 'author_create' %}">Создать автора</a> <a href="{% url 'author_create' %}">Создать автора</a>
</div> </div>
{% endblock %} {% 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 @@ ...@@ -26,6 +26,7 @@
class="btn btn-success" class="btn btn-success"
value="Оставить комментарий"> value="Оставить комментарий">
</form> </form>
<a href="{% url 'article_update' article.pk %}">Изменить статью</a>
</div> </div>
</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"> <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container"> <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"> <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>
......
...@@ -2,7 +2,7 @@ from django.urls import path ...@@ -2,7 +2,7 @@ from django.urls import path
from .views import ( from .views import (
article_list_view, article_list_view,
ArticleDetailView, CommentView, 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 = [ urlpatterns = [
...@@ -21,7 +21,16 @@ urlpatterns = [ ...@@ -21,7 +21,16 @@ urlpatterns = [
CommentView.as_view(), CommentView.as_view(),
name="add_comment" name="add_comment"
), ),
path(
'article/create/',
CreateArticleView.as_view(),
name='article_create'
),
path(
'article/<int:pk>/update',
ArticleUpdateView.as_view(),
name='article_update'
),
path( path(
'create/', 'create/',
AuthorView.as_view(), AuthorView.as_view(),
......
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.views import View from django.views import View
from django.views.generic import FormView
from .helpers.views import CustomFormView
from articles.models import Article, Author from articles.models import Article, Author
from .forms import AuthorForm, CommentForm from .forms import AuthorForm, CommentForm, ArticleForm
def article_list_view(request): def article_list_view(request):
...@@ -25,6 +28,62 @@ def author_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): class AuthorView(View):
url_pattern = 'authors/author_create.html' 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