Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
AE
Sith
Commits
cfbb6f4e
Commit
cfbb6f4e
authored
Nov 25, 2016
by
Skia
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Lot of small improvement in SAS
parent
0b23d39e
Pipeline
#429
passed with stage
in 2 minutes and 14 seconds
Changes
13
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
170 additions
and
43 deletions
+170
-43
core/admin.py
core/admin.py
+6
-1
core/lookups.py
core/lookups.py
+8
-1
core/migrations/0011_auto_20161124_0848.py
core/migrations/0011_auto_20161124_0848.py
+36
-0
core/models.py
core/models.py
+10
-5
core/static/core/style.css
core/static/core/style.css
+2
-1
core/templates/core/user_pictures.jinja
core/templates/core/user_pictures.jinja
+3
-3
migrate.py
migrate.py
+58
-28
sas/admin.py
sas/admin.py
+3
-1
sas/models.py
sas/models.py
+7
-0
sas/templates/sas/album.jinja
sas/templates/sas/album.jinja
+2
-1
sas/templates/sas/picture.jinja
sas/templates/sas/picture.jinja
+9
-2
sas/urls.py
sas/urls.py
+2
-0
sas/views.py
sas/views.py
+24
-0
No files found.
core/admin.py
View file @
cfbb6f4e
from
django.contrib
import
admin
from
ajax_select
import
make_ajax_form
from
core.models
import
User
,
Page
,
RealGroup
,
SithFile
from
django.contrib.auth.models
import
Group
as
AuthGroup
...
...
@@ -7,5 +8,9 @@ admin.site.register(User)
admin
.
site
.
unregister
(
AuthGroup
)
admin
.
site
.
register
(
RealGroup
)
admin
.
site
.
register
(
Page
)
admin
.
site
.
register
(
SithFile
)
@
admin
.
register
(
SithFile
)
class
SithFileAdmin
(
admin
.
ModelAdmin
):
form
=
make_ajax_form
(
SithFile
,
{
'parent'
:
'files'
,
# ManyToManyField
})
core/lookups.py
View file @
cfbb6f4e
...
...
@@ -2,7 +2,7 @@ from django.core.exceptions import PermissionDenied
from
ajax_select
import
register
,
LookupChannel
from
core.views.site
import
search_user
from
core.models
import
User
,
Group
from
core.models
import
User
,
Group
,
SithFile
from
club.models
import
Club
from
counter.models
import
Product
,
Counter
from
accounting.models
import
ClubAccount
,
Company
...
...
@@ -77,6 +77,13 @@ class ProductsLookup(RightManagedLookupChannel):
def
format_item_display
(
self
,
item
):
return
"%s (%s)"
%
(
item
.
name
,
item
.
code
)
@
register
(
'files'
)
class
SithFileLookup
(
RightManagedLookupChannel
):
model
=
SithFile
def
get_query
(
self
,
q
,
request
):
return
self
.
model
.
objects
.
filter
(
name__icontains
=
q
)[:
50
]
@
register
(
'club_accounts'
)
class
ClubAccountLookup
(
RightManagedLookupChannel
):
model
=
ClubAccount
...
...
core/migrations/0011_auto_20161124_0848.py
0 → 100644
View file @
cfbb6f4e
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
import
django.utils.timezone
import
core.models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'core'
,
'0010_sithfile_is_in_sas'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'sithfile'
,
name
=
'compressed'
,
field
=
models
.
FileField
(
verbose_name
=
'compressed file'
,
upload_to
=
core
.
models
.
get_compressed_directory
,
null
=
True
,
blank
=
True
,
max_length
=
256
),
),
migrations
.
AlterField
(
model_name
=
'sithfile'
,
name
=
'date'
,
field
=
models
.
DateTimeField
(
verbose_name
=
'date'
,
default
=
django
.
utils
.
timezone
.
now
),
),
migrations
.
AlterField
(
model_name
=
'sithfile'
,
name
=
'file'
,
field
=
models
.
FileField
(
verbose_name
=
'file'
,
upload_to
=
core
.
models
.
get_directory
,
null
=
True
,
blank
=
True
,
max_length
=
256
),
),
migrations
.
AlterField
(
model_name
=
'sithfile'
,
name
=
'thumbnail'
,
field
=
models
.
FileField
(
verbose_name
=
'thumbnail'
,
upload_to
=
core
.
models
.
get_thumbnail_directory
,
null
=
True
,
blank
=
True
,
max_length
=
256
),
),
]
core/models.py
View file @
cfbb6f4e
...
...
@@ -317,7 +317,9 @@ class User(AbstractBaseUser):
def
get_short_name
(
self
):
"Returns the short name for the user."
return
self
.
first_name
if
self
.
nick_name
:
return
self
.
nick_name
return
self
.
first_name
+
" "
+
self
.
last_name
def
get_display_name
(
self
):
"""
...
...
@@ -501,16 +503,16 @@ def get_thumbnail_directory(instance, filename):
class
SithFile
(
models
.
Model
):
name
=
models
.
CharField
(
_
(
'file name'
),
max_length
=
256
,
blank
=
False
)
parent
=
models
.
ForeignKey
(
'self'
,
related_name
=
"children"
,
verbose_name
=
_
(
"parent"
),
null
=
True
,
blank
=
True
)
file
=
models
.
FileField
(
upload_to
=
get_directory
,
verbose_name
=
_
(
"file"
),
null
=
True
,
blank
=
True
)
compressed
=
models
.
FileField
(
upload_to
=
get_compressed_directory
,
verbose_name
=
_
(
"compressed file"
),
null
=
True
,
blank
=
True
)
thumbnail
=
models
.
FileField
(
upload_to
=
get_thumbnail_directory
,
verbose_name
=
_
(
"thumbnail"
),
null
=
True
,
blank
=
True
)
file
=
models
.
FileField
(
upload_to
=
get_directory
,
verbose_name
=
_
(
"file"
),
max_length
=
256
,
null
=
True
,
blank
=
True
)
compressed
=
models
.
FileField
(
upload_to
=
get_compressed_directory
,
verbose_name
=
_
(
"compressed file"
),
max_length
=
256
,
null
=
True
,
blank
=
True
)
thumbnail
=
models
.
FileField
(
upload_to
=
get_thumbnail_directory
,
verbose_name
=
_
(
"thumbnail"
),
max_length
=
256
,
null
=
True
,
blank
=
True
)
owner
=
models
.
ForeignKey
(
User
,
related_name
=
"owned_files"
,
verbose_name
=
_
(
"owner"
))
edit_groups
=
models
.
ManyToManyField
(
Group
,
related_name
=
"editable_files"
,
verbose_name
=
_
(
"edit group"
),
blank
=
True
)
view_groups
=
models
.
ManyToManyField
(
Group
,
related_name
=
"viewable_files"
,
verbose_name
=
_
(
"view group"
),
blank
=
True
)
is_folder
=
models
.
BooleanField
(
_
(
"is folder"
),
default
=
True
)
mime_type
=
models
.
CharField
(
_
(
'mime type'
),
max_length
=
30
)
size
=
models
.
IntegerField
(
_
(
"size"
),
default
=
0
)
date
=
models
.
DateTimeField
(
_
(
'date'
),
auto_now
=
True
)
date
=
models
.
DateTimeField
(
_
(
'date'
),
default
=
timezone
.
now
)
is_moderated
=
models
.
BooleanField
(
_
(
"is moderated"
),
default
=
False
)
asked_for_removal
=
models
.
BooleanField
(
_
(
"asked for removal"
),
default
=
False
)
is_in_sas
=
models
.
BooleanField
(
_
(
"is in the SAS"
),
default
=
False
)
...
...
@@ -629,6 +631,9 @@ class SithFile(models.Model):
def
get_download_url
(
self
):
return
reverse
(
'core:download'
,
kwargs
=
{
'file_id'
:
self
.
id
})
def
__str__
(
self
):
return
self
.
get_parent_path
()
+
"/"
+
self
.
name
class
LockError
(
Exception
):
"""There was a lock error on the object"""
pass
...
...
core/static/core/style.css
View file @
cfbb6f4e
...
...
@@ -314,10 +314,11 @@ textarea {
text-align
:
center
;
padding
:
5px
;
width
:
200px
;
height
:
1
33
px
;
height
:
1
40
px
;
background
:
#eee
;
box-shadow
:
black
2px
2px
10px
;
margin
:
10px
;
vertical-align
:
top
;
}
.album
img
{
...
...
core/templates/core/user_pictures.jinja
View file @
cfbb6f4e
...
...
@@ -6,12 +6,12 @@
{%
endblock
%}
{%
block
content
%}
{%
for
r
in
user
.pictures.exclude
(
picture
=
None
)
.
values
(
'user__pictures__picture__parent'
)
.
distinct
()
%}
{%
for
r
in
profile
.pictures.exclude
(
picture
=
None
)
.
values
(
'user__pictures__picture__parent'
)
.
distinct
()
%}
<div
style=
"padding: 10px"
>
{%
set
album
=
user
.pictures.
filter
(
picture__parent
=
r
[
'user__pictures__picture__parent'
])
.
first
()
.
picture.parent
%}
{%
set
album
=
profile
.pictures.
filter
(
picture__parent
=
r
[
'user__pictures__picture__parent'
])
.
first
()
.
picture.parent
%}
<h4>
{{
album.name
}}
</h4>
<hr>
{%
for
r
in
user
.pictures.exclude
(
picture
=
None
)
.
filter
(
picture__parent
=
album
)
%}
{%
for
r
in
profile
.pictures.exclude
(
picture
=
None
)
.
filter
(
picture__parent
=
album
)
.
order_by
(
'id'
)
%}
<div
class=
"picture"
>
<a
href=
"
{{
url
(
"sas:picture"
,
picture_id
=
r.picture.id
)
}}
#pict"
>
<img
src=
"
{{
r.picture.as_picture.get_download_thumb_url
()
}}
"
alt=
"
{{
r.picture.get_display_name
()
}}
"
style=
"max-width: 100%"
/>
...
...
migrate.py
View file @
cfbb6f4e
...
...
@@ -25,7 +25,7 @@ from counter.models import Customer, Counter, Selling, Refilling, Product, Produ
from
subscription.models
import
Subscription
,
Subscriber
from
eboutic.models
import
Invoice
,
InvoiceItem
from
accounting.models
import
BankAccount
,
ClubAccount
,
GeneralJournal
,
Operation
,
AccountingType
,
Company
,
SimplifiedAccountingType
,
Label
from
sas.models
import
Album
,
Picture
from
sas.models
import
Album
,
Picture
,
PeoplePictureRelation
db
=
MySQLdb
.
connect
(
**
settings
.
OLD_MYSQL_INFOS
)
start
=
datetime
.
datetime
.
now
()
...
...
@@ -1029,7 +1029,7 @@ def migrate_sas():
album_link
=
{}
picture_link
=
{}
FILE_ROOT
=
"/data/sas/"
Album
.
objects
.
filter
(
i
s_in_sas
=
True
).
delete
()
SithFile
.
objects
.
filter
(
i
d__gt
=
18886
).
delete
()
print
(
"Album/Pictures deleted"
)
cur
=
db
.
cursor
(
MySQLdb
.
cursors
.
SSDictCursor
)
cur
.
execute
(
"""
...
...
@@ -1044,44 +1044,74 @@ def migrate_sas():
album_link
[
str
(
r
[
'id_catph'
])]
=
a
.
id
except
Exception
as
e
:
print
(
"FAIL to migrate Album: %s"
%
(
repr
(
e
)))
print
(
"Album moved, need to make the tree"
)
cur
.
execute
(
"""
SELECT *
FROM sas_cat_photos
"""
)
for
r
in
cur
:
try
:
p
=
Album
.
objects
.
filter
(
id
=
album_link
[
r
[
'id_catph_parent'
]]).
first
()
a
=
Album
.
objects
.
filter
(
id
=
album_link
[
r
[
'id_catph'
]]).
first
()
p
=
Album
.
objects
.
filter
(
id
=
album_link
[
str
(
r
[
'id_catph_parent'
]
)
]).
first
()
a
=
Album
.
objects
.
filter
(
id
=
album_link
[
str
(
r
[
'id_catph'
]
)
]).
first
()
a
.
parent
=
p
a
.
save
()
except
:
pass
print
(
"Album migrated at %s"
%
datetime
.
datetime
.
now
())
print
(
"Running time: %s"
%
(
datetime
.
datetime
.
now
()
-
start
))
# cur.execute("""
# SELECT *
# FROM sas_photos
# """)
# for r in cur:
# try:
# user = User.objects.filter(id=r['id_utilisateur']).first() or root
# parent = Album.objects.filter(id=album_link[str(r['id_catph'])]).first()
cur
.
execute
(
"""
SELECT *
FROM sas_photos
"""
)
for
r
in
cur
:
try
:
user
=
User
.
objects
.
filter
(
id
=
r
[
'id_utilisateur'
]).
first
()
or
root
parent
=
Album
.
objects
.
filter
(
id
=
album_link
[
str
(
r
[
'id_catph'
])]).
first
()
file_name
=
FILE_ROOT
if
r
[
'date_prise_vue'
]:
file_name
+=
r
[
'date_prise_vue'
].
strftime
(
"%Y/%m/%d"
)
else
:
file_name
+=
'/'
.
join
([
"1970"
,
"01"
,
"01"
])
file_name
+=
"/"
+
str
(
r
[
'id_photo'
])
+
".jpg"
file
=
File
(
open
(
file_name
,
"rb"
))
file
.
name
=
str
(
r
[
'id_photo'
])
+
".jpg"
# p = Picture(
# name=to_unicode(str(r['id_photo'])),
# owner=user,
# is_moderated=True,
# is_folder=False,
# mime_type="image/jpeg",
# parent=parent
# )
# for f in p._meta.local_fields:
# if f.name == "date":
# f.auto_now = False
# p.date = r['date_ajout_ph'].replace(tzinfo=timezone('Europe/Paris'))
# p.save()
# picture_link[str(r['id_photo'])] = p.id
# except Exception as e:
# print("FAIL to migrate Picture: %s" % (repr(e)))
p
=
Picture
(
name
=
to_unicode
(
str
(
r
[
'id_photo'
]))
+
".jpg"
,
owner
=
user
,
is_moderated
=
True
,
is_folder
=
False
,
mime_type
=
"image/jpeg"
,
parent
=
parent
,
file
=
file
,
)
if
r
[
'date_prise_vue'
]:
p
.
date
=
r
[
'date_prise_vue'
].
replace
(
tzinfo
=
timezone
(
'Europe/Paris'
))
else
:
p
.
date
=
r
[
'date_ajout_ph'
].
replace
(
tzinfo
=
timezone
(
'Europe/Paris'
))
for
f
in
p
.
_meta
.
local_fields
:
if
f
.
name
==
"date"
:
f
.
auto_now
=
False
p
.
generate_thumbnails
()
db2
=
MySQLdb
.
connect
(
**
settings
.
OLD_MYSQL_INFOS
)
cur2
=
db2
.
cursor
(
MySQLdb
.
cursors
.
SSDictCursor
)
cur2
.
execute
(
"""
SELECT *
FROM sas_personnes_photos
WHERE id_photo = %s
"""
,
(
r
[
'id_photo'
],
))
for
r2
in
cur2
:
try
:
u
=
User
.
objects
.
filter
(
id
=
r2
[
'id_utilisateur'
]).
first
()
if
u
:
PeoplePictureRelation
(
user
=
u
,
picture
=
p
).
save
()
except
:
print
(
"Fail to associate user %d to picture %d"
%
(
r2
[
'id_utilisateur'
],
p
.
id
))
picture_link
[
str
(
r
[
'id_photo'
])]
=
p
.
id
except
Exception
as
e
:
pass
print
(
"FAIL to migrate Picture: %s"
%
(
repr
(
e
)))
cur
.
close
()
print
(
"SAS migrated at %s"
%
datetime
.
datetime
.
now
())
print
(
"Running time: %s"
%
(
datetime
.
datetime
.
now
()
-
start
))
...
...
sas/admin.py
View file @
cfbb6f4e
...
...
@@ -4,5 +4,7 @@ from sas.models import *
admin
.
site
.
register
(
Album
)
admin
.
site
.
register
(
Picture
)
# admin.site.register(Picture)
admin
.
site
.
register
(
PeoplePictureRelation
)
sas/models.py
View file @
cfbb6f4e
from
django.db
import
models
from
django.core.urlresolvers
import
reverse_lazy
,
reverse
from
django.conf
import
settings
from
django.core.urlresolvers
import
reverse
from
django.utils.translation
import
ugettext_lazy
as
_
...
...
@@ -36,6 +37,9 @@ class Picture(SithFile):
def
get_download_thumb_url
(
self
):
return
reverse
(
'sas:download_thumb'
,
kwargs
=
{
'picture_id'
:
self
.
id
})
def
get_absolute_url
(
self
):
return
reverse
(
'sas:picture'
,
kwargs
=
{
'picture_id'
:
self
.
id
})
def
generate_thumbnails
(
self
):
im
=
Image
.
open
(
BytesIO
(
self
.
file
.
read
()))
try
:
...
...
@@ -94,3 +98,6 @@ class PeoplePictureRelation(models.Model):
class
Meta
:
unique_together
=
[
'user'
,
'picture'
]
def
__str__
(
self
):
return
self
.
user
.
get_display_name
()
+
" - "
+
str
(
self
.
picture
)
sas/templates/sas/album.jinja
View file @
cfbb6f4e
...
...
@@ -15,6 +15,7 @@
{%
block
content
%}
<a
href=
"
{{
url
(
'sas:main'
)
}}
"
>
SAS
</a>
>
{{
print_path
(
album.parent
)
}}
{{
album.get_display_name
()
}}
<h3>
{{
album.get_display_name
()
}}
</h3>
<a
href=
"
{{
url
(
'sas:album_edit'
,
album_id
=
album.id
)
}}
"
>
{%
trans
%}
Edit
{%
endtrans
%}
</a><br>
<hr>
<div>
{%
for
a
in
album.children.
filter
(
is_folder
=
True
,
is_moderated
=
True
)
.
all
()
%}
...
...
@@ -33,7 +34,7 @@
{%
endfor
%}
</div>
<div>
{%
for
p
in
album.children.
filter
(
is_folder
=
False
,
is_moderated
=
True
)
.
all
(
)
%}
{%
for
p
in
album.children.
filter
(
is_folder
=
False
,
is_moderated
=
True
)
.
order_by
(
'id'
)
%}
{%
if
p.as_picture.can_be_viewed_by
(
user
)
%}
<div
class=
"picture"
>
<a
href=
"
{{
url
(
"sas:picture"
,
picture_id
=
p.id
)
}}
#pict"
>
...
...
sas/templates/sas/picture.jinja
View file @
cfbb6f4e
...
...
@@ -35,7 +35,8 @@
{%
block
content
%}
<a
href=
"
{{
url
(
'sas:main'
)
}}
"
>
SAS
</a>
>
{{
print_path
(
picture.parent
)
}}
{{
picture.get_display_name
()
}}
<h3>
{{
picture.get_display_name
()
}}
</h3>
(
{{
picture.parent.children.filter
(
id__lte
=
picture.id
)
.
count
()
}}
/
{{
picture.parent.children.count
()
}}
)
<h3>
{{
picture.get_display_name
()
}}
</h3>
<div
style=
"display: inline-block; width: 19%; vertical-align: top; overflow: hidden; float: right"
>
<div>
<div
id=
"prev"
>
...
...
@@ -60,7 +61,7 @@
<ul>
{%
for
r
in
picture.people.all
()
%}
<li>
<a
href=
"
{{
r.user.get_absolute_url
()
}}
"
>
{{
r.user.get_
display
_name
()
}}
</a>
<a
href=
"
{{
r.user.get_absolute_url
()
}}
"
>
{{
r.user.get_
short
_name
()
}}
</a>
{%
if
user
==
r.user
or
user.is_in_group
(
settings.SITH_SAS_ADMIN_GROUP_ID
)
%}
<a
href=
"?remove_user=
{{
r.user.id
}}
"
>
{%
trans
%}
Delete
{%
endtrans
%}
</a>
{%
endif
%}
...
...
@@ -73,12 +74,18 @@
<p><input
type=
"submit"
value=
"
{%
trans
%}
Go
{%
endtrans
%}
"
/></p>
</form>
</div>
<div>
<h5>
{%
trans
%}
Infos
{%
endtrans
%}
</h5>
<p>
{%
trans
%}
Date:
{%
endtrans
%}{{
picture.date
|
date
(
DATETIME_FORMAT
)
}}
</p>
<p>
{{
picture.parent.children.filter
(
id__lte
=
picture.id
)
.
count
()
}}
/
{{
picture.parent.children.count
()
}}
</p>
</div>
<div>
<h5>
{%
trans
%}
Tools
{%
endtrans
%}
</h5>
<p>
<a
href=
"
{{
picture.get_download_url
()
}}
"
>
{%
trans
%}
HD version
{%
endtrans
%}
</a>
</p>
<p
style=
"font-size: smaller;"
>
<a
href=
"
{{
url
(
'sas:picture_edit'
,
picture_id
=
picture.id
)
}}
"
>
{%
trans
%}
Edit
{%
endtrans
%}
</a><br>
<a
href=
"?rotate_left"
>
{%
trans
%}
Rotate left
{%
endtrans
%}
</a><br>
<a
href=
"?rotate_right"
>
{%
trans
%}
Rotate right
{%
endtrans
%}
</a><br>
<a
href=
"?ask_removal"
>
{%
trans
%}
Ask for removal
{%
endtrans
%}
</a><br>
...
...
sas/urls.py
View file @
cfbb6f4e
...
...
@@ -6,7 +6,9 @@ urlpatterns = [
url
(
r
'^$'
,
SASMainView
.
as_view
(),
name
=
'main'
),
url
(
r
'^moderation$'
,
ModerationView
.
as_view
(),
name
=
'moderation'
),
url
(
r
'^album/(?P<album_id>[0-9]+)$'
,
AlbumView
.
as_view
(),
name
=
'album'
),
url
(
r
'^album/(?P<album_id>[0-9]+)/edit$'
,
AlbumEditView
.
as_view
(),
name
=
'album_edit'
),
url
(
r
'^picture/(?P<picture_id>[0-9]+)$'
,
PictureView
.
as_view
(),
name
=
'picture'
),
url
(
r
'^picture/(?P<picture_id>[0-9]+)/edit$'
,
PictureEditView
.
as_view
(),
name
=
'picture_edit'
),
url
(
r
'^picture/(?P<picture_id>[0-9]+)/download$'
,
send_pict
,
name
=
'download'
),
url
(
r
'^picture/(?P<picture_id>[0-9]+)/download/compressed$'
,
send_compressed
,
name
=
'download_compressed'
),
url
(
r
'^picture/(?P<picture_id>[0-9]+)/download/thumb$'
,
send_thumb
,
name
=
'download_thumb'
),
...
...
sas/views.py
View file @
cfbb6f4e
...
...
@@ -5,6 +5,7 @@ from django.views.generic.edit import UpdateView, CreateView, DeleteView, Proces
from
django.utils.translation
import
ugettext
as
_
from
django.utils
import
timezone
from
django.conf
import
settings
from
django.forms.models
import
modelform_factory
from
django
import
forms
from
django.core.exceptions
import
PermissionDenied
...
...
@@ -192,4 +193,27 @@ class ModerationView(TemplateView):
kwargs
[
'pictures'
]
=
Picture
.
objects
.
filter
(
is_moderated
=
False
,
is_in_sas
=
True
).
order_by
(
'id'
)
return
kwargs
class
PictureEditForm
(
forms
.
ModelForm
):
class
Meta
:
model
=
Picture
fields
=
[
'name'
,
'parent'
]
parent
=
make_ajax_field
(
Picture
,
'parent'
,
'files'
,
help_text
=
""
)
class
AlbumEditForm
(
forms
.
ModelForm
):
class
Meta
:
model
=
Album
fields
=
[
'name'
,
'parent'
]
parent
=
make_ajax_field
(
Album
,
'parent'
,
'files'
,
help_text
=
""
)
class
PictureEditView
(
UpdateView
):
model
=
Picture
form_class
=
PictureEditForm
template_name
=
'core/edit.jinja'
pk_url_kwarg
=
"picture_id"
class
AlbumEditView
(
UpdateView
):
model
=
Album
form_class
=
AlbumEditForm
template_name
=
'core/edit.jinja'
pk_url_kwarg
=
"album_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