Skip to content

Commit 2882d29

Browse files
authored
Merge pull request #46 from jedie/refactor-item-attachments
NEW: Add files to items.
2 parents e60eccc + 6dfe29c commit 2882d29

File tree

12 files changed

+231
-75
lines changed

12 files changed

+231
-75
lines changed

README.creole

+1
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ Files are separated into: "/src/" and "/development/"
155155
== history
156156

157157
* [[https://github.com/jedie/PyInventory/compare/v0.9.0...master|compare v0.9.0...master]] **dev**
158+
* NEW: It's not possible to upload file(s) to item.
158159
* Add a auto login if Django dev. server is used.
159160
** tbc
160161
* [[https://github.com/jedie/PyInventory/compare/v0.8.4...v0.9.0|v0.9.0 - 11.04.2021]]

README.rst

+3-1
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ history
218218

219219
* `compare v0.9.0...master <https://github.com/jedie/PyInventory/compare/v0.9.0...master>`_ **dev**
220220

221+
* NEW: It's not possible to upload file(s) to item.
222+
221223
* Add a auto login if Django dev. server is used.
222224

223225
* tbc
@@ -377,4 +379,4 @@ donation
377379

378380
------------
379381

380-
``Note: this file is generated from README.creole 2021-04-28 16:53:58 with "python-creole"``
382+
``Note: this file is generated from README.creole 2021-04-28 19:03:46 with "python-creole"``

src/inventory/admin/item.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from inventory.admin.base import BaseUserAdmin
1212
from inventory.forms import ItemModelModelForm
1313
from inventory.models import ItemLinkModel, ItemModel
14-
from inventory.models.item import ItemImageModel
14+
from inventory.models.item import ItemFileModel, ItemImageModel
1515

1616

1717
class UserInlineMixin:
@@ -49,6 +49,14 @@ def preview(self, instance):
4949
readonly_fields = ('preview',)
5050

5151

52+
class ItemFileModelInline(UserInlineMixin, SortableInlineAdminMixin, admin.TabularInline):
53+
model = ItemFileModel
54+
extra = 0
55+
fields = (
56+
'position', 'file', 'name', 'tags'
57+
)
58+
59+
5260
class ItemModelResource(ModelResource):
5361
class Meta:
5462
model = ItemModel
@@ -134,7 +142,7 @@ def column_item(self, obj):
134142
)}),
135143
)
136144
readonly_fields = ('id', 'create_dt', 'update_dt', 'user')
137-
inlines = (ItemImageModelInline, ItemLinkModelInline)
145+
inlines = (ItemImageModelInline, ItemFileModelInline, ItemLinkModelInline)
138146

139147
def get_changelist(self, request, **kwargs):
140148
self.user = request.user
240 Bytes
Binary file not shown.

src/inventory/locale/de/LC_MESSAGES/django.po

+24-27
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ msgid ""
77
msgstr ""
88
"Project-Id-Version: \n"
99
"Report-Msgid-Bugs-To: \n"
10-
"POT-Creation-Date: 2020-11-15 13:09+0100\n"
11-
"PO-Revision-Date: 2020-11-15 13:14+0100\n"
10+
"POT-Creation-Date: 2021-04-28 18:31+0200\n"
11+
"PO-Revision-Date: 2021-04-28 18:29+0200\n"
1212
"Last-Translator: Jens Diemer\n"
1313
"Language-Team: \n"
1414
"Language: de\n"
@@ -50,8 +50,8 @@ msgstr "Benutzer"
5050

5151
msgid "BaseModel.user.help_text"
5252
msgstr ""
53-
" Der Benutzer dem dieser Eintrag gehört und verwalten kann (Wird "
54-
"automatisch gesetzt)"
53+
"Der Benutzer dem dieser Eintrag gehört und verwalten kann (Wird automatisch "
54+
"gesetzt)"
5555

5656
msgid "BaseModel.name.verbose_name"
5757
msgstr "Name"
@@ -65,6 +65,12 @@ msgstr "Tags"
6565
msgid "BaseModel.tags.help_text"
6666
msgstr " "
6767

68+
msgid "BaseItemAttachmentModel.name.verbose_name"
69+
msgstr "Name"
70+
71+
msgid "BaseItemAttachmentModel.name.help_text"
72+
msgstr "Optionalen Namen (Wird automatisch aus dem Dateinamen gesetzt)"
73+
6874
msgid "ItemModel.kind.verbose_name"
6975
msgstr "Art"
7076

@@ -100,7 +106,7 @@ msgstr "Übergeordnet"
100106

101107
msgid "ItemModel.parent.help_text"
102108
msgstr ""
103-
" Eingebaut in einem anderen Gegenstand? (e.g.: Grafikkarte eingebaut in "
109+
"Eingebaut in einem anderen Gegenstand? (e.g.: Grafikkarte eingebaut in "
104110
"Rechner)"
105111

106112
msgid "ItemModel.lent_to.verbose_name"
@@ -170,22 +176,26 @@ msgid "ItemImageModel.image.verbose_name"
170176
msgstr "Bild"
171177

172178
msgid "ItemImageModel.image.help_text"
173-
msgstr ""
174-
175-
msgid "ItemImageModel.name.verbose_name"
176-
msgstr "Name"
177-
178-
msgid "ItemImageModel.name.help_text"
179-
msgstr ""
180-
"Optionalen Namen passend zum Bild (Wird automatisch aus dem Dateinamen "
181-
"gesetzt)"
179+
msgstr " "
182180

183181
msgid "ItemImageModel.verbose_name"
184182
msgstr "Bild"
185183

186184
msgid "ItemImageModel.verbose_name_plural"
187185
msgstr "Bilder"
188186

187+
msgid "ItemFileModel.file.verbose_name"
188+
msgstr "Datei"
189+
190+
msgid "ItemFileModel.file.help_text"
191+
msgstr ""
192+
193+
msgid "ItemFileModel.verbose_name"
194+
msgstr "Datei"
195+
196+
msgid "ItemFileModel.verbose_name_plural"
197+
msgstr "Dateien"
198+
189199
msgid "BaseLink.name.verbose_name"
190200
msgstr "Name"
191201

@@ -227,16 +237,3 @@ msgstr "Standort"
227237

228238
msgid "LocationModel.verbose_name_plural"
229239
msgstr "Standorte"
230-
231-
#, python-format
232-
msgid "Image \"%(path)s\" does not exist"
233-
msgstr ""
234-
235-
msgid "German"
236-
msgstr ""
237-
238-
msgid "English"
239-
msgstr ""
240-
241-
msgid "Log in"
242-
msgstr ""
322 Bytes
Binary file not shown.

src/inventory/locale/en/LC_MESSAGES/django.po

+23-24
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ msgid ""
77
msgstr ""
88
"Project-Id-Version: \n"
99
"Report-Msgid-Bugs-To: \n"
10-
"POT-Creation-Date: 2020-11-15 13:09+0100\n"
11-
"PO-Revision-Date: 2020-11-15 13:15+0100\n"
10+
"POT-Creation-Date: 2021-04-28 18:31+0200\n"
11+
"PO-Revision-Date: 2021-04-28 18:30+0200\n"
1212
"Last-Translator: Jens Diemer\n"
1313
"Language-Team: \n"
1414
"Language: en\n"
@@ -50,7 +50,7 @@ msgstr "User"
5050

5151
msgid "BaseModel.user.help_text"
5252
msgstr ""
53-
" The user who is the owner of this entry and can manage it (will be set "
53+
"The user who is the owner of this entry and can manage it (will be set "
5454
"automatically)"
5555

5656
msgid "BaseModel.name.verbose_name"
@@ -65,11 +65,17 @@ msgstr "Tags"
6565
msgid "BaseModel.tags.help_text"
6666
msgstr " "
6767

68+
msgid "BaseItemAttachmentModel.name.verbose_name"
69+
msgstr "Name"
70+
71+
msgid "BaseItemAttachmentModel.name.help_text"
72+
msgstr ""
73+
6874
msgid "ItemModel.kind.verbose_name"
6975
msgstr "Kind"
7076

7177
msgid "ItemModel.kind.help_text"
72-
msgstr ""
78+
msgstr " "
7379

7480
msgid "ItemModel.producer.verbose_name"
7581
msgstr "Producer"
@@ -170,18 +176,24 @@ msgstr "Image"
170176
msgid "ItemImageModel.image.help_text"
171177
msgstr " "
172178

173-
msgid "ItemImageModel.name.verbose_name"
174-
msgstr "Name"
175-
176-
msgid "ItemImageModel.name.help_text"
177-
msgstr ""
178-
179179
msgid "ItemImageModel.verbose_name"
180180
msgstr "Image"
181181

182182
msgid "ItemImageModel.verbose_name_plural"
183183
msgstr "Images"
184184

185+
msgid "ItemFileModel.file.verbose_name"
186+
msgstr "File"
187+
188+
msgid "ItemFileModel.file.help_text"
189+
msgstr " "
190+
191+
msgid "ItemFileModel.verbose_name"
192+
msgstr "File"
193+
194+
msgid "ItemFileModel.verbose_name_plural"
195+
msgstr "Files"
196+
185197
msgid "BaseLink.name.verbose_name"
186198
msgstr "Name"
187199

@@ -204,7 +216,7 @@ msgid "Link.page_title.verbose_name"
204216
msgstr "Page title"
205217

206218
msgid "Link.page_title.help_text"
207-
msgstr ""
219+
msgstr " "
208220

209221
msgid "LocationModel.description.verbose_name"
210222
msgstr "Description"
@@ -223,16 +235,3 @@ msgstr "Location"
223235

224236
msgid "LocationModel.verbose_name_plural"
225237
msgstr "Locations"
226-
227-
#, python-format
228-
msgid "Image \"%(path)s\" does not exist"
229-
msgstr ""
230-
231-
msgid "German"
232-
msgstr ""
233-
234-
msgid "English"
235-
msgstr ""
236-
237-
msgid "Log in"
238-
msgstr ""
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Generated by Django 2.2.20 on 2021-04-28 15:44
2+
3+
from django.db import migrations, models
4+
import tagulous.models.models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('inventory', '0005_serve_uploads_by_django_tools'),
11+
]
12+
13+
operations = [
14+
migrations.AlterField(
15+
model_name='itemimagemodel',
16+
name='name',
17+
field=models.CharField(blank=True, help_text='BaseItemAttachmentModel.name.help_text', max_length=255, null=True, verbose_name='BaseItemAttachmentModel.name.verbose_name'),
18+
),
19+
migrations.CreateModel(
20+
name='Tagulous_BaseItemAttachmentModel_tags',
21+
fields=[
22+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
23+
('name', models.CharField(max_length=255, unique=True)),
24+
('slug', models.SlugField()),
25+
('count', models.IntegerField(default=0, help_text='Internal counter of how many times this tag is in use')),
26+
('protected', models.BooleanField(default=False, help_text='Will not be deleted when the count reaches 0')),
27+
],
28+
options={
29+
'ordering': ('name',),
30+
'abstract': False,
31+
'unique_together': {('slug',)},
32+
},
33+
bases=(tagulous.models.models.BaseTagModel, models.Model),
34+
),
35+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Generated by Django 2.2.20 on 2021-04-28 15:54
2+
3+
from django.conf import settings
4+
from django.db import migrations, models
5+
import django.db.models.deletion
6+
import django_tools.serve_media_app.models
7+
import tagulous.models.fields
8+
import tagulous.models.models
9+
import uuid
10+
11+
12+
class Migration(migrations.Migration):
13+
14+
dependencies = [
15+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
16+
('inventory', '0006_refactor_image_model'),
17+
]
18+
19+
operations = [
20+
migrations.CreateModel(
21+
name='Tagulous_ItemFileModel_tags',
22+
fields=[
23+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
24+
('name', models.CharField(max_length=255, unique=True)),
25+
('slug', models.SlugField()),
26+
('count', models.IntegerField(default=0, help_text='Internal counter of how many times this tag is in use')),
27+
('protected', models.BooleanField(default=False, help_text='Will not be deleted when the count reaches 0')),
28+
],
29+
options={
30+
'ordering': ('name',),
31+
'abstract': False,
32+
'unique_together': {('slug',)},
33+
},
34+
bases=(tagulous.models.models.BaseTagModel, models.Model),
35+
),
36+
migrations.CreateModel(
37+
name='ItemFileModel',
38+
fields=[
39+
('create_dt', models.DateTimeField(blank=True, editable=False, help_text='ModelTimetrackingMixin.create_dt.help_text', null=True, verbose_name='ModelTimetrackingMixin.create_dt.verbose_name')),
40+
('update_dt', models.DateTimeField(blank=True, editable=False, help_text='ModelTimetrackingMixin.update_dt.help_text', null=True, verbose_name='ModelTimetrackingMixin.update_dt.verbose_name')),
41+
('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='BaseModel.id.help_text', primary_key=True, serialize=False, verbose_name='BaseModel.id.verbose_name')),
42+
('name', models.CharField(blank=True, help_text='BaseItemAttachmentModel.name.help_text', max_length=255, null=True, verbose_name='BaseItemAttachmentModel.name.verbose_name')),
43+
('position', models.PositiveSmallIntegerField(default=0)),
44+
('file', models.FileField(help_text='ItemFileModel.file.help_text', upload_to=django_tools.serve_media_app.models.user_directory_path, verbose_name='ItemFileModel.file.verbose_name')),
45+
('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inventory.ItemModel')),
46+
('tags', tagulous.models.fields.TagField(_set_tag_meta=True, blank=True, case_sensitive=False, force_lowercase=False, help_text='BaseModel.tags.help_text', max_count=10, space_delimiter=False, to='inventory.Tagulous_ItemFileModel_tags', verbose_name='BaseModel.tags.verbose_name')),
47+
('user', models.ForeignKey(editable=False, help_text='BaseModel.user.help_text', on_delete=django.db.models.deletion.CASCADE, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='BaseModel.user.verbose_name')),
48+
],
49+
options={
50+
'verbose_name': 'ItemFileModel.verbose_name',
51+
'verbose_name_plural': 'ItemFileModel.verbose_name_plural',
52+
'ordering': ('position',),
53+
},
54+
),
55+
]

src/inventory/models/base.py

+31
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,34 @@ def __str__(self):
4343

4444
class Meta:
4545
abstract = True
46+
47+
48+
class BaseItemAttachmentModel(BaseModel):
49+
"""
50+
Base model to store files or images to Items
51+
"""
52+
name = models.CharField(
53+
null=True, blank=True,
54+
max_length=255,
55+
verbose_name=_('BaseItemAttachmentModel.name.verbose_name'),
56+
help_text=_('BaseItemAttachmentModel.name.help_text')
57+
)
58+
item = models.ForeignKey('ItemModel', on_delete=models.CASCADE)
59+
position = models.PositiveSmallIntegerField(
60+
# Note: Will be set in admin via adminsortable2
61+
# The JavaScript which performs the sorting is 1-indexed !
62+
default=0, blank=False, null=False
63+
)
64+
65+
def __str__(self):
66+
return self.name
67+
68+
def full_clean(self, **kwargs):
69+
if self.user_id is None:
70+
# inherit owner of this link from item instance
71+
self.user_id = self.item.user_id
72+
73+
return super().full_clean(**kwargs)
74+
75+
class Meta:
76+
abstract = True

0 commit comments

Comments
 (0)