asdf

parent dbbb72f7
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.forms.models import ModelForm from django.forms.models import ModelForm
from django.forms import CharField from django.forms import CharField, Form
from articles.models import Article, Author, Comment from articles.models import Article, Author, Comment
...@@ -25,21 +25,10 @@ class CommentForm(ModelForm): ...@@ -25,21 +25,10 @@ class CommentForm(ModelForm):
class ArticleForm(ModelForm): 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: class Meta:
model = Article model = Article
fields = "__all__" fields = "__all__"
class SearchForm(Form):
search = CharField(max_length=100, required=False, label="Найти")
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.views import View from django.views import View
from django.views.generic import TemplateView
class CustomFormView(View): class CustomFormView(View):
...@@ -9,6 +10,7 @@ class CustomFormView(View): ...@@ -9,6 +10,7 @@ class CustomFormView(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
form = self.form_class() form = self.form_class()
context = self.get_context_data(form=form) context = self.get_context_data(form=form)
return render(request, self.template_name, context=context) return render(request, self.template_name, context=context)
...@@ -30,3 +32,13 @@ class CustomFormView(View): ...@@ -30,3 +32,13 @@ class CustomFormView(View):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
return kwargs return kwargs
class ListView(TemplateView):
model = None
context_key = 'objects'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context[self.context_key] = self.model.objects.all()
return context
\ No newline at end of file
...@@ -2,9 +2,11 @@ ...@@ -2,9 +2,11 @@
{% block content %} {% block content %}
<form action="{% url 'article_create' %}" method="POST"> <form action="{% url 'article_create' %}" method="POST">
<div class="container">
{% csrf_token %} {% csrf_token %}
{{ form.as_p }} {{ form.as_p }}
<input type="submit" value="create"> <input type="submit" value="create">
</div>
</form> </form>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -2,25 +2,32 @@ ...@@ -2,25 +2,32 @@
{% block content %} {% block content %}
<div class="container"> <div class="container">
<form class="d-flex" method="GET">
<input name="search" class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
<th scope="col">#</th> <th scope="col">#</th>
<th scope="col">Title</th> <th scope="col">Title</th>
<th scope="col">Author</th> <th scope="col">Author</th>
<th scope="col">Date</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for article in articles %} {% for article in articles %}
<tr> <tr>
<th scope="row">1</th> <th scope="row">{{ forloop.counter }}</th>
<td><a href="{% url 'article_detail' article.pk %}">{{ article.title }}</a></td> <td><a href="{% url 'article_detail' article.pk %}">{{ article.title }}</a></td>
<td>{{ article.author.name }}</td> <td>{{ article.author.name }}</td>
<td>{{ article.created_at|date:"d M Y" }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<a href="{% url 'article_create' %}">Создать статью</a> <a href="{% url 'article_create' %}">Создать статью</a>
<a href="{% url 'author_create' %}">Создать автора</a> <a href="{% url 'author_create' %}">Создать автора</a>
{% include 'partial/pagination.html' %}
</div> </div>
{% endblock %} {% endblock %}
\ No newline at end of file
{% extends 'base.html' %} {% extends 'base.html' %}
{% block content %} {% block content %}
<div class="container">
<form action="{% url 'article_update' article.pk %}" method="POST"> <form action="{% url 'article_update' article.pk %}" method="POST">
{% csrf_token %} {% csrf_token %}
<div class="col-md-6">
<label for="title" class="form-label">Название: </label>
<input type="text" name="title" class="form-control" id="title">
</div>
<div class="col-md-6">
<label for="body" class="form-label">Тело статьи: </label>
<textarea name="body" id="body" cols="30" rows="20"></textarea>
</div>
<div class="col-md-6">
<label for="author" class="form-label">Автор: </label>
{{ form.author }}
</div>
<div class="col-md-6">
<label for="tags" class="form-label">Теги: </label>
<select name="tags" id="tags" multiple>
{{ form.tags }}
</select>
</div>
{{ form.as_p }} {{ form.as_p }}
<input type="submit" value="create"> <input type="submit" value="create">
</form> </form>
</div>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
{% block content %} {% block content %}
<div class="container"> <div class="container">
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
...@@ -13,7 +14,7 @@ ...@@ -13,7 +14,7 @@
<tbody> <tbody>
{% for author in authors %} {% for author in authors %}
<tr> <tr>
<th scope="row">1</th> <th scope="row">{{ forloop.counter }}</th>
<td>{{ author.name }}</td> <td>{{ author.name }}</td>
<td> <td>
<div style="display: flex;"> <div style="display: flex;">
...@@ -25,6 +26,9 @@ ...@@ -25,6 +26,9 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<a href="{% url 'author_create' %}">Создать автора</a> <a href="{% url 'author_create' %}">Создать автора</a>
{% include 'partial/pagination.html' %}
</div> </div>
{% endblock %} {% endblock %}
\ No newline at end of file
<style>
.pagination {
text-align: center;
}
.pagination a, .pagination .page-disabled {
display: inline-block;
border: solid 1px #6a7ddd;
border-radius: 3px;
padding: 5px;
margin: 3px;
}
.pagination a {
background: #6a7ddd;
color: white;
text-decoration: none;
}
.pagination a:hover {
background: #6a7dff;
text-decoration: underline;
}
.pagination .page-disabled {
background: #6a7dcc;
color: #dddddd
}
.pagination .current-page {
display: inline-block;
}
.pagination .current-page input {
width: 50px;
padding: 5px 7px;
font-size: inherit;
border-radius: 5px;
text-align: center;
border: solid 1px gray;
}
</style>
<div class="pagination">
<span class="step-links">
<a href="?page=1">&laquo; В начало</a>
{% if page_obj.has_previous %}
<a href="?page={{ page_obj.previous_page_number }}">Назад</a>
{% else %}
<span class="page-disabled">Назад</span>
{% endif %}
<form class="current-page" method="get">
<label for="page">
Страница <input type="text" name="page" id="page" value="{{ page_obj.number }}">
из {{ page_obj.paginator.num_pages }}.
</label>
</form>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">Далее</a>
{% else %}
<span class="page-disabled">Далее</span>
{% endif %}
<a href="?page={{ page_obj.paginator.num_pages }}">В конец &raquo;</a>
</span>
</div>
\ No newline at end of file
from django.urls import path from django.urls import path
from .views import ( from .views import (
article_list_view, ArticleListView,
ArticleDetailView, CommentView, ArticleDetailView, CommentView,
author_list_view, author_edit_view, author_delete_view, AuthorView, CreateArticleView, ArticleUpdateView author_edit_view, author_delete_view, AuthorView, CreateArticleView, ArticleUpdateView, AuthorListView
) )
urlpatterns = [ urlpatterns = [
path( path(
'', '',
article_list_view, ArticleListView.as_view(),
name="article_list" name="article_list"
), ),
path( path(
...@@ -38,7 +38,7 @@ urlpatterns = [ ...@@ -38,7 +38,7 @@ urlpatterns = [
), ),
path( path(
'authors/', 'authors/',
author_list_view, AuthorListView.as_view(),
name="author_list" name="author_list"
), ),
......
from django.db.models import Q
from django.shortcuts import render, redirect, get_object_or_404 from django.shortcuts import render, redirect, get_object_or_404
from django.template.defaultfilters import urlencode
from django.urls import reverse from django.urls import reverse
from django.views import View from django.views import View
from django.views.generic import FormView from django.views.generic import FormView, ListView
from .helpers.views import CustomFormView from .helpers.views import CustomFormView
from articles.models import Article, Author from articles.models import Article, Author
from .forms import AuthorForm, CommentForm, ArticleForm from .forms import AuthorForm, CommentForm, ArticleForm, SearchForm
def article_list_view(request): class ArticleListView(ListView):
if request.method == "GET": form = SearchForm
articles = Article.objects.all() search_fields = ('title', 'name')
return render(
request,
template_name="articles/article_list.html",
context={'articles': articles}
)
template_name = 'articles/list.html'
model = Article
context_object_name = 'articles'
ordering = ['-created_at']
paginate_by = 5
paginate_orphans = 1
def author_list_view(request): def get(self, request, *args, **kwargs):
if request.method == "GET": self.form = self.get_search_form()
authors = Author.objects.all() self.search_value = self.get_search_value()
return render( return super().get(request, *args, **kwargs)
request,
template_name="authors/author_list.html", def get_context_data(self, *, object_list=None, **kwargs):
context={'authors': authors} context = super().get_context_data(object_list=object_list, **kwargs)
) context['form'] = self.form
if self.search_value:
context['query'] = urlencode({
'search': self.search_value
})
return context
def get_search_form(self):
return self.form(self.request.GET)
def get_search_value(self):
if self.form.is_valid():
return self.form.cleaned_data.get('search')
def get_queryset(self):
queryset = super().get_queryset()
if self.search_value:
query = Q(title__icontains=self.search_value) | \
Q(author__name__icontains=self.search_value)
queryset = queryset.filter(query)
return queryset
class AuthorListView(ListView):
template_name = 'authors/list.html'
model = Author
context_object_name = 'authors'
ordering = ['name']
paginate_by = 5
class CreateArticleView(CustomFormView): class CreateArticleView(CustomFormView):
...@@ -84,8 +115,9 @@ class ArticleUpdateView(FormView): ...@@ -84,8 +115,9 @@ class ArticleUpdateView(FormView):
pk = self.kwargs.get('pk') pk = self.kwargs.get('pk')
return get_object_or_404(Article, pk=pk) return get_object_or_404(Article, pk=pk)
class AuthorView(View): class AuthorView(View):
url_pattern = 'authors/author_create.html' url_pattern = 'authors/create.html'
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
form = AuthorForm() form = AuthorForm()
...@@ -130,7 +162,7 @@ def create_author_view(request): ...@@ -130,7 +162,7 @@ def create_author_view(request):
form = AuthorForm() form = AuthorForm()
return render( return render(
request, request,
'authors/author_create.html', 'authors/create.html',
context={'form': form}) context={'form': form})
if request.method == "POST": if request.method == "POST":
form = AuthorForm(request.POST) form = AuthorForm(request.POST)
...@@ -145,7 +177,7 @@ def author_edit_view(request, pk): ...@@ -145,7 +177,7 @@ def author_edit_view(request, pk):
form = AuthorForm(instance=author) form = AuthorForm(instance=author)
return render( return render(
request, request,
'authors/author_update.html', 'authors/update.html',
context={'form': form, "pk": pk}) context={'form': form, "pk": pk})
if request.method == "POST": if request.method == "POST":
form = AuthorForm(request.POST) form = AuthorForm(request.POST)
......
...@@ -104,7 +104,7 @@ AUTH_PASSWORD_VALIDATORS = [ ...@@ -104,7 +104,7 @@ AUTH_PASSWORD_VALIDATORS = [
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/ # https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = 'en-us' LANGUAGE_CODE = 'ru'
TIME_ZONE = 'UTC' TIME_ZONE = 'UTC'
......
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