Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
A
article_proj
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Владислав Андреев
article_proj
Commits
dbbb72f7
Commit
dbbb72f7
authored
Aug 23, 2021
by
Владислав Андреев
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Commmit
parent
41987858
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
245 additions
and
13 deletions
+245
-13
forms.py
articles/forms.py
+31
-0
__init__.py
articles/helpers/__init__.py
+0
-0
views.py
articles/helpers/views.py
+32
-0
0012_articletag.py
articles/migrations/0012_articletag.py
+22
-0
0013_article_number.py
articles/migrations/0013_article_number.py
+18
-0
0014_auto_20210819_1433.py
articles/migrations/0014_auto_20210819_1433.py
+22
-0
0015_alter_article_created_at.py
articles/migrations/0015_alter_article_created_at.py
+18
-0
models.py
articles/models.py
+8
-9
article_list.html
articles/templates/articles/article_list.html
+1
-0
create.html
articles/templates/articles/create.html
+10
-0
detail.html
articles/templates/articles/detail.html
+1
-0
update.html
articles/templates/articles/update.html
+10
-0
navbar.html
articles/templates/partial/navbar.html
+1
-1
urls.py
articles/urls.py
+11
-2
views.py
articles/views.py
+60
-1
No files found.
articles/forms.py
View file @
dbbb72f7
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__"
articles/helpers/__init__.py
0 → 100644
View file @
dbbb72f7
articles/helpers/views.py
0 → 100644
View file @
dbbb72f7
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
articles/migrations/0012_articletag.py
0 → 100644
View file @
dbbb72f7
# 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
=
'Тег'
)),
],
),
]
articles/migrations/0013_article_number.py
0 → 100644
View file @
dbbb72f7
# 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
),
),
]
articles/migrations/0014_auto_20210819_1433.py
0 → 100644
View file @
dbbb72f7
# 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
),
),
]
articles/migrations/0015_alter_article_created_at.py
0 → 100644
View file @
dbbb72f7
# 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
),
),
]
articles/models.py
View file @
dbbb72f7
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}"
articles/templates/articles/article_list.html
View file @
dbbb72f7
...
@@ -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
articles/templates/articles/create.html
0 → 100644
View file @
dbbb72f7
{% 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
articles/templates/articles/detail.html
View file @
dbbb72f7
...
@@ -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>
...
...
articles/templates/articles/update.html
0 → 100644
View file @
dbbb72f7
{% 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
articles/templates/partial/navbar.html
View file @
dbbb72f7
<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>
...
...
articles/urls.py
View file @
dbbb72f7
...
@@ -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
(),
...
...
articles/views.py
View file @
dbbb72f7
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'
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment