Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
A
ap-11_django
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
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
Давид Ли
ap-11_django
Commits
23744ea8
Commit
23744ea8
authored
Jul 28, 2023
by
Давид Ли
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lesson 54
parent
3dea0324
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
301 additions
and
60 deletions
+301
-60
admin.py
accounts/admin.py
+4
-0
forms.py
accounts/forms.py
+42
-1
login.html
accounts/templates/login.html
+1
-1
registration.html
accounts/templates/registration.html
+12
-0
urls.py
accounts/urls.py
+9
-0
views.py
accounts/views.py
+30
-4
settings.py
core/settings.py
+2
-2
urls.py
core/urls.py
+4
-27
auth.json
fixtures/auth.json
+72
-0
dump.json
fixtures/dump.json
+0
-0
users_dump.json
fixtures/users_dump.json
+0
-0
forms.py
web/forms.py
+2
-2
0014_auto_20230727_1734.py
web/migrations/0014_auto_20230727_1734.py
+26
-0
0015_alter_article_options.py
web/migrations/0015_alter_article_options.py
+17
-0
article.py
web/models/article.py
+8
-5
comment.py
web/models/comment.py
+5
-5
article_create.html
web/templates/article/article_create.html
+1
-0
article_detail.html
web/templates/article/article_detail.html
+9
-4
index.html
web/templates/article/index.html
+7
-3
update.html
web/templates/article/update.html
+1
-0
base.html
web/templates/base.html
+4
-1
urls.py
web/urls.py
+27
-0
article.py
web/views/article.py
+12
-4
comment.py
web/views/comment.py
+6
-1
No files found.
accounts/admin.py
View file @
23744ea8
from
django.contrib
import
admin
from
accounts.models
import
User
# Register your models here.
admin
.
site
.
register
(
User
)
accounts/forms.py
View file @
23744ea8
from
django
import
forms
from
django.contrib.auth.forms
import
AuthenticationForm
from
django.contrib.auth.forms
import
AuthenticationForm
,
UserCreationForm
from
django.contrib.auth
import
password_validation
from
accounts.models
import
User
class
LoginForm
(
AuthenticationForm
):
...
...
@@ -19,3 +22,41 @@ class LoginForm(AuthenticationForm):
}
)
)
class
RegisterForm
(
UserCreationForm
):
password1
=
forms
.
CharField
(
label
=
"Password"
,
strip
=
False
,
widget
=
forms
.
PasswordInput
(
attrs
=
{
'autocomplete'
:
'new-password'
,
'class'
:
'form-control mb-3'
}
),
help_text
=
password_validation
.
password_validators_help_text_html
(),
)
password2
=
forms
.
CharField
(
label
=
"Password confirmation"
,
widget
=
forms
.
PasswordInput
(
attrs
=
{
'autocomplete'
:
'new-password'
,
'class'
:
'form-control mb-3'
}
),
strip
=
False
,
help_text
=
"Enter the same password as before, for verification."
,
)
class
Meta
(
UserCreationForm
.
Meta
):
model
=
User
fields
=
[
'username'
,
'first_name'
,
'last_name'
,
'email'
,
'password1'
,
'password2'
]
widgets
=
{
'username'
:
forms
.
TextInput
(
attrs
=
{
'class'
:
'form-control mb-3'
}),
'first_name'
:
forms
.
TextInput
(
attrs
=
{
'class'
:
'form-control mb-3'
}),
'last_name'
:
forms
.
TextInput
(
attrs
=
{
'class'
:
'form-control mb-3'
}),
'email'
:
forms
.
EmailInput
(
attrs
=
{
'class'
:
'form-control mb-3'
}),
}
accounts/templates/login.html
View file @
23744ea8
...
...
@@ -5,7 +5,7 @@
{% endblock %}
{% block content %}
<form
action=
"{% url 'login' %}"
method=
"post"
>
<form
action=
"{% url 'login' %}
?next={{ request.GET.next }}
"
method=
"post"
>
{% csrf_token %}
{% include 'partial/form.html' with button_text='Login' %}
</form>
...
...
accounts/templates/registration.html
0 → 100644
View file @
23744ea8
{% extends 'base.html' %}
{% block title %}
<h1
class=
"text-center my-3"
>
Registration
</h1>
{% endblock %}
{% block content %}
<form
action=
"{% url 'register' %}?next={{ request.GET.next }}"
method=
"post"
>
{% csrf_token %}
{% include 'partial/form.html' with button_text='Register' %}
</form>
{% endblock %}
accounts/urls.py
0 → 100644
View file @
23744ea8
from
django.urls
import
path
from
accounts
import
views
urlpatterns
=
[
path
(
'login/'
,
views
.
LoginView
.
as_view
(),
name
=
'login'
),
path
(
'logout/'
,
views
.
LogoutView
.
as_view
(),
name
=
'logout'
),
path
(
'register/'
,
views
.
RegisterView
.
as_view
(),
name
=
'register'
)
]
accounts/views.py
View file @
23744ea8
from
django.contrib.auth
import
views
,
login
from
django.views.generic
import
CreateView
from
django.shortcuts
import
redirect
from
django.urls
import
reverse_lazy
from
django.contrib.auth
import
views
from
accounts.forms
import
LoginForm
from
accounts.forms
import
LoginForm
,
RegisterForm
from
accounts.models
import
User
class
LoginView
(
views
.
LoginView
):
class
AuthSuccessUrlMixin
:
def
get_success_url
(
self
):
return
self
.
request
.
GET
.
get
(
'next'
,
self
.
request
.
POST
.
get
(
'next'
,
reverse_lazy
(
'main_page'
)
)
)
class
LoginView
(
AuthSuccessUrlMixin
,
views
.
LoginView
):
template_name
=
'login.html'
form_class
=
LoginForm
class
LogoutView
(
views
.
LogoutView
):
pass
def
get_next_page
(
self
):
return
self
.
request
.
META
.
get
(
'HTTP_REFERER'
)
class
RegisterView
(
AuthSuccessUrlMixin
,
CreateView
):
model
=
User
template_name
=
'registration.html'
form_class
=
RegisterForm
def
form_valid
(
self
,
form
):
user
=
form
.
save
()
login
(
self
.
request
,
user
)
return
redirect
(
self
.
get_success_url
())
core/settings.py
View file @
23744ea8
...
...
@@ -142,5 +142,5 @@ SHELL_PLUS = "bpython"
AUTH_USER_MODEL
=
'accounts.User'
LOGIN_URL
=
'login'
LOGIN_REDIRECT_URL
=
'main_page'
LOGOUT_REDIRECT_URL
=
'main_page'
#
LOGIN_REDIRECT_URL = 'main_page'
#
LOGOUT_REDIRECT_URL = 'main_page'
core/urls.py
View file @
23744ea8
...
...
@@ -16,37 +16,14 @@ Including another URLconf
from
django.conf
import
settings
from
django.conf.urls.static
import
static
from
django.contrib
import
admin
from
django.urls
import
path
from
django.urls
import
path
,
include
from
web
import
views
from
accounts
import
views
as
accounts_views
urlpatterns
=
[
path
(
'admin/'
,
admin
.
site
.
urls
),
path
(
''
,
views
.
MainPageRedirectView
.
as_view
()),
path
(
'auth/login/'
,
accounts_views
.
LoginView
.
as_view
(),
name
=
'login'
),
path
(
'auth/logout/'
,
accounts_views
.
LogoutView
.
as_view
(),
name
=
'logout'
),
path
(
'articles/'
,
views
.
ArticleIndexView
.
as_view
(),
name
=
'main_page'
),
path
(
'articles/add/'
,
views
.
ArticleCreateView
.
as_view
(),
name
=
'articles-add'
),
path
(
'articles/<int:id>/'
,
views
.
ArticleDetailView
.
as_view
(),
name
=
'articles-detail'
),
path
(
'articles/<int:id>/edit'
,
views
.
ArticleUpdateView
.
as_view
(),
name
=
'article_update'
),
path
(
'articles/<int:id>/delete'
,
views
.
ArticleDeleteView
.
as_view
(),
name
=
'delete_article'
),
path
(
'articles/article_id/comments/add/'
,
views
.
CommentCreateView
.
as_view
(),
name
=
'comment_create'
),
path
(
'comments/<int:id>/edit'
,
views
.
CommentUpdateView
.
as_view
(),
name
=
'comment_update'
),
path
(
'comments/<int:id>/delete'
,
views
.
CommentDeleteView
.
as_view
(),
name
=
'comment_delete'
),
path
(
''
,
include
(
'web.urls'
)),
path
(
'auth/'
,
include
(
'accounts.urls'
))
]
+
static
(
settings
.
MEDIA_URL
,
document_root
=
settings
.
MEDIA_ROOT
)
fixtures/auth.json
0 → 100644
View file @
23744ea8
[
{
"model"
:
"web.article"
,
"pk"
:
1
,
"fields"
:
{
"title"
:
"fjdsgbafdgjkafgbjaf"
,
"status"
:
"check"
,
"text"
:
"gadpfgkadfnglndafgafd"
,
"author"
:
1
,
"created_at"
:
"2023-07-27T11:40:39.768Z"
,
"updated_at"
:
"2023-07-27T11:40:39.768Z"
,
"tags"
:
[]
}
},
{
"model"
:
"web.article"
,
"pk"
:
2
,
"fields"
:
{
"title"
:
"fasdffdasgas"
,
"status"
:
"check"
,
"text"
:
"asdfsadfasdfsadf"
,
"author"
:
5
,
"created_at"
:
"2023-07-27T11:40:56.056Z"
,
"updated_at"
:
"2023-07-27T11:50:41.848Z"
,
"tags"
:
[]
}
},
{
"model"
:
"web.comment"
,
"pk"
:
1
,
"fields"
:
{
"article"
:
2
,
"text"
:
"dfadfasdfasdf"
,
"author"
:
5
,
"created_at"
:
"2023-07-27T11:42:42.869Z"
,
"updated_at"
:
"2023-07-27T11:42:42.869Z"
}
},
{
"model"
:
"web.comment"
,
"pk"
:
2
,
"fields"
:
{
"article"
:
2
,
"text"
:
"dfsafdsafasdfsadf"
,
"author"
:
5
,
"created_at"
:
"2023-07-27T11:42:45.916Z"
,
"updated_at"
:
"2023-07-27T11:42:45.916Z"
}
},
{
"model"
:
"web.comment"
,
"pk"
:
3
,
"fields"
:
{
"article"
:
2
,
"text"
:
"fsadfasdfsadfsadfsadfdasf"
,
"author"
:
5
,
"created_at"
:
"2023-07-27T11:42:48.064Z"
,
"updated_at"
:
"2023-07-27T11:42:48.064Z"
}
},
{
"model"
:
"web.comment"
,
"pk"
:
4
,
"fields"
:
{
"article"
:
2
,
"text"
:
"dfasfsagadsg"
,
"author"
:
5
,
"created_at"
:
"2023-07-27T11:44:47.632Z"
,
"updated_at"
:
"2023-07-27T11:44:47.632Z"
}
}
]
web/
fixtures/dump.json
→
fixtures/dump.json
View file @
23744ea8
File moved
web/
fixtures/users_dump.json
→
fixtures/users_dump.json
View file @
23744ea8
File moved
web/forms.py
View file @
23744ea8
...
...
@@ -18,7 +18,7 @@ class ArticleModelForm(forms.ModelForm):
fields
=
(
'title'
,
'author'
,
'status'
,
'text'
,
'tags'
)
widgets
=
{
'title'
:
forms
.
TextInput
(
attrs
=
{
'class'
:
'form-control mb-3'
}),
'author'
:
forms
.
Text
Input
(
attrs
=
{
'class'
:
'form-control mb-3'
}),
'author'
:
forms
.
Hidden
Input
(
attrs
=
{
'class'
:
'form-control mb-3'
}),
'status'
:
forms
.
Select
(
attrs
=
{
'class'
:
'form-select mb-3'
}),
'text'
:
forms
.
Textarea
(
attrs
=
{
'class'
:
'form-control mb-3'
}),
'tags'
:
forms
.
CheckboxSelectMultiple
(
attrs
=
{
'class'
:
'mb-3'
})
...
...
@@ -38,7 +38,7 @@ class CommentModelForm(forms.ModelForm):
fields
=
[
'author'
,
'text'
,
'article'
]
widgets
=
{
'text'
:
forms
.
TextInput
(
attrs
=
{
'class'
:
'form-control mb-3'
}),
'author'
:
forms
.
Text
Input
(
attrs
=
{
'class'
:
'form-control mb-3'
}),
'author'
:
forms
.
Hidden
Input
(
attrs
=
{
'class'
:
'form-control mb-3'
}),
'article'
:
forms
.
HiddenInput
()
}
...
...
web/migrations/0014_auto_20230727_1734.py
0 → 100644
View file @
23744ea8
# Generated by Django 3.2.19 on 2023-07-27 11:34
from
django.conf
import
settings
from
django.db
import
migrations
,
models
import
django.db.models.deletion
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
migrations
.
swappable_dependency
(
settings
.
AUTH_USER_MODEL
),
(
'web'
,
'0013_alter_article_title'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'article'
,
name
=
'author'
,
field
=
models
.
ForeignKey
(
default
=
1
,
on_delete
=
django
.
db
.
models
.
deletion
.
CASCADE
,
related_name
=
'articles'
,
to
=
settings
.
AUTH_USER_MODEL
,
verbose_name
=
'Автор'
),
),
migrations
.
AlterField
(
model_name
=
'comment'
,
name
=
'author'
,
field
=
models
.
ForeignKey
(
default
=
1
,
on_delete
=
django
.
db
.
models
.
deletion
.
CASCADE
,
related_name
=
'comments'
,
to
=
settings
.
AUTH_USER_MODEL
,
verbose_name
=
'Автор'
),
),
]
web/migrations/0015_alter_article_options.py
0 → 100644
View file @
23744ea8
# Generated by Django 3.2.19 on 2023-07-27 11:54
from
django.db
import
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'web'
,
'0014_auto_20230727_1734'
),
]
operations
=
[
migrations
.
AlterModelOptions
(
name
=
'article'
,
options
=
{
'permissions'
:
[(
'can_eat_pizza'
,
'Может съесть пиццу'
)],
'verbose_name'
:
'статью'
,
'verbose_name_plural'
:
'статьи'
},
),
]
web/models/article.py
View file @
23744ea8
...
...
@@ -38,11 +38,11 @@ class Article(models.Model):
verbose_name
=
'Текст'
)
author
=
models
.
CharField
(
max_length
=
100
,
null
=
False
,
blank
=
False
,
default
=
'Unknown
'
,
author
=
models
.
ForeignKey
(
'accounts.User'
,
on_delete
=
models
.
CASCADE
,
default
=
1
,
related_name
=
'articles
'
,
verbose_name
=
'Автор'
)
...
...
@@ -59,6 +59,9 @@ class Article(models.Model):
class
Meta
:
verbose_name
=
'статью'
verbose_name_plural
=
'статьи'
permissions
=
[
(
'can_eat_pizza'
,
'Может съесть пиццу'
)
]
def
__str__
(
self
):
return
f
'{self.author}: {self.title}'
web/models/comment.py
View file @
23744ea8
...
...
@@ -12,11 +12,11 @@ class Comment(models.Model):
text
=
models
.
TextField
(
max_length
=
400
,
verbose_name
=
'Текст'
)
author
=
models
.
CharField
(
max_length
=
40
,
null
=
True
,
blank
=
True
,
default
=
'Аноним
'
,
author
=
models
.
ForeignKey
(
'accounts.User'
,
on_delete
=
models
.
CASCADE
,
default
=
1
,
related_name
=
'comments
'
,
verbose_name
=
'Автор'
)
...
...
web/templates/article/article_create.html
View file @
23744ea8
...
...
@@ -10,6 +10,7 @@
<form
action=
"/articles/add/"
method=
"post"
>
{% csrf_token %}
{% include 'partial/form.html' with button_text='Create' %}
<input
type=
"hidden"
name=
"author"
value=
"{{ request.user.id }}"
>
</form>
{% endblock %}
web/templates/article/article_detail.html
View file @
23744ea8
...
...
@@ -25,7 +25,9 @@
<hr>
<a
href=
"{% url 'article_update' article.pk %}"
class=
"btn btn-primary mt-4 me-3"
>
Edit
</a>
{% if perms.web.change_article or article.author == request.user %}
<a
href=
"{% url 'article_update' article.pk %}"
class=
"btn btn-primary mt-4 me-3"
>
Edit
</a>
{% endif %}
<form
action=
"{% url 'delete_article' article.pk %}"
method=
"POST"
onsubmit=
"return confirm('Are you sure?')"
>
{% csrf_token %}
<button
class=
"btn btn-danger mt-4"
>
Delete
</button>
...
...
@@ -39,6 +41,7 @@
{% csrf_token %}
{% include 'partial/form.html' with button_text='add' %}
<input
type=
"hidden"
name=
"article"
value=
"{{ article.id }}"
>
<input
type=
"hidden"
name=
"author"
value=
"{{ request.user.id }}"
>
</form>
{% for comment in comments %}
...
...
@@ -46,9 +49,11 @@
<div
class=
"card-header d-flex justify-content-between"
>
{{ comment.author }}
<div
class=
"d-flex justify-content-between"
>
<a
href=
"{% url 'comment_update' id=comment.id %}"
class=
"me-5"
>
<i
class=
"fa fa-regular fa-pen-to-square"
></i>
</a>
{% if perms.web.change_comment or request.user == comment.author %}
<a
href=
"{% url 'comment_update' id=comment.id %}"
class=
"me-5"
>
<i
class=
"fa fa-regular fa-pen-to-square"
></i>
</a>
{% endif %}
<form
action=
"{% url 'comment_delete' id=comment.id %}"
method=
"POST"
onsubmit=
"return confirm('Are you sure?')"
>
{% csrf_token %}
...
...
web/templates/article/index.html
View file @
23744ea8
...
...
@@ -4,7 +4,11 @@
{% block content %}
<h1>
Articles
</h1>
<a
href=
"{% url 'articles-add' %}"
class=
"btn btn-primary"
>
Создать
</a>
{% if perms.web.add_article %}
<a
href=
"{% url 'articles-add' %}"
class=
"btn btn-primary"
>
Создать
</a>
{% endif %}
{% include 'partial/search_form.html' %}
{% for article in articles %}
<br>
...
...
@@ -12,13 +16,13 @@
<br>
<h2>
{{ article.title }}
</h2>
{% if user.is_authenticated %
}
{# {% if user.is_authenticated %}#
}
<p>
<a
href=
"{% url 'articles-detail' id=article.id %}"
>
Подробнее
</a>
</p>
{% endif %
}
{# {% endif %}#
}
<br>
<hr>
<br>
...
...
web/templates/article/update.html
View file @
23744ea8
...
...
@@ -6,6 +6,7 @@
{% block content %}
<form
action=
"{% url 'article_update' article.pk %}"
method=
"post"
>
{% csrf_token %}
{% include 'partial/form.html' with button_text='Update' abc='123' %}
</form>
{% endblock %}
...
...
web/templates/base.html
View file @
23744ea8
...
...
@@ -56,7 +56,10 @@
{% else %}
<li
class=
"nav-item"
>
<a
class=
"nav-link"
href=
"{% url 'login' %}"
>
Login
</a>
<a
class=
"nav-link"
href=
"{% url 'login' %}?next={{ request.get_full_path }}"
>
Login
</a>
</li>
<li
class=
"nav-item"
>
<a
class=
"nav-link"
href=
"{% url 'register' %}?next={{ request.get_full_path }}"
>
Register
</a>
</li>
{% endif %}
...
...
web/urls.py
0 → 100644
View file @
23744ea8
from
django.urls
import
path
from
web
import
views
urlpatterns
=
[
path
(
'articles/'
,
views
.
ArticleIndexView
.
as_view
(),
name
=
'main_page'
),
path
(
'articles/add/'
,
views
.
ArticleCreateView
.
as_view
(),
name
=
'articles-add'
),
path
(
'articles/<int:id>/'
,
views
.
ArticleDetailView
.
as_view
(),
name
=
'articles-detail'
),
path
(
'articles/<int:id>/edit'
,
views
.
ArticleUpdateView
.
as_view
(),
name
=
'article_update'
),
path
(
'articles/<int:id>/delete'
,
views
.
ArticleDeleteView
.
as_view
(),
name
=
'delete_article'
),
path
(
'comments/add/'
,
views
.
CommentCreateView
.
as_view
(),
name
=
'comment_create'
),
path
(
'comments/<int:id>/edit'
,
views
.
CommentUpdateView
.
as_view
(),
name
=
'comment_update'
),
path
(
'comments/<int:id>/delete'
,
views
.
CommentDeleteView
.
as_view
(),
name
=
'comment_delete'
),
]
web/views/article.py
View file @
23744ea8
...
...
@@ -2,7 +2,8 @@ from urllib.parse import urlencode
from
django.urls
import
reverse
,
reverse_lazy
from
django.db.models
import
Q
from
django.contrib.auth.mixins
import
LoginRequiredMixin
from
django.contrib.auth.mixins
import
LoginRequiredMixin
,
PermissionRequiredMixin
,
UserPassesTestMixin
from
django.core.exceptions
import
PermissionDenied
from
django.views.generic
import
(
ListView
,
DetailView
,
...
...
@@ -51,16 +52,18 @@ class ArticleIndexView(ListView):
return
self
.
form
.
cleaned_data
.
get
(
'search'
)
class
ArticleCreateView
(
CreateView
):
class
ArticleCreateView
(
PermissionRequiredMixin
,
CreateView
):
template_name
=
'article/article_create.html'
model
=
Article
form_class
=
ArticleModelForm
permission_required
=
'web.add_article'
permission_denied_message
=
'You have no rights'
def
get_success_url
(
self
):
return
reverse
(
'articles-detail'
,
kwargs
=
{
'id'
:
self
.
object
.
id
})
class
ArticleDetailView
(
LoginRequiredMixin
,
DetailView
):
class
ArticleDetailView
(
DetailView
):
raise_exception
=
True
template_name
=
'article/article_detail.html'
model
=
Article
...
...
@@ -75,12 +78,17 @@ class ArticleDetailView(LoginRequiredMixin, DetailView):
)
class
ArticleUpdateView
(
LoginRequired
Mixin
,
UpdateView
):
class
ArticleUpdateView
(
UserPassesTest
Mixin
,
UpdateView
):
model
=
Article
template_name
=
'article/update.html'
form_class
=
ArticleModelForm
context_object_name
=
'article'
pk_url_kwarg
=
'id'
permission_required
=
'web.change_article'
def
test_func
(
self
):
return
self
.
get_object
()
.
author
==
self
.
request
.
user
or
\
self
.
request
.
user
.
has_perm
(
'web.change_article'
)
def
get_success_url
(
self
):
return
reverse
(
'articles-detail'
,
kwargs
=
{
'id'
:
self
.
object
.
id
})
...
...
web/views/comment.py
View file @
23744ea8
...
...
@@ -4,6 +4,7 @@ from django.views.generic import (
UpdateView
,
DeleteView
)
from
django.contrib.auth.mixins
import
PermissionRequiredMixin
from
web.forms
import
CommentModelForm
from
web.models
import
Comment
...
...
@@ -17,17 +18,21 @@ class CommentCreateView(CreateView):
return
reverse
(
'articles-detail'
,
kwargs
=
{
'id'
:
self
.
object
.
article
.
id
})
class
CommentUpdateView
(
UpdateView
):
class
CommentUpdateView
(
PermissionRequiredMixin
,
UpdateView
):
model
=
Comment
template_name
=
'comment/create_update.html'
context_object_name
=
'comment'
pk_url_kwarg
=
'id'
form_class
=
CommentModelForm
extra_context
=
{
'button_text'
:
'Update'
,
'title'
:
'Update comment'
}
permission_required
=
'web.change_comment'
def
get_initial
(
self
):
return
self
.
object
.
__dict__
def
has_permission
(
self
):
return
super
()
.
has_permission
()
or
self
.
request
.
user
==
self
.
get_object
()
.
author
def
get_success_url
(
self
):
return
reverse
(
'articles-detail'
,
kwargs
=
{
'id'
:
self
.
object
.
article
.
id
})
...
...
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