From c5d639f271966dae80042a7fb384c79be0a76bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20Marti=CC=81n?= Date: Mon, 25 Aug 2014 20:58:25 +0200 Subject: [PATCH] Added manga collections --- shelfzilla/apps/manga/admin.py | 56 ++++- ...collection__add_field_volume_collection.py | 226 ++++++++++++++++++ shelfzilla/apps/manga/models.py | 42 +++- shelfzilla/apps/manga/views/series.py | 15 +- shelfzilla/locale/es/LC_MESSAGES/django.mo | Bin 5152 -> 5259 bytes shelfzilla/locale/es/LC_MESSAGES/django.po | 81 ++++--- .../themes/bootflat/static/less/fixes.less | 13 + .../bootflat/templates/homepage/home.html | 26 +- .../templates/manga/series/detail.html | 38 ++- .../manga/series/includes/volume.html | 11 +- .../manga/series/includes/volume_slim.html | 16 ++ 11 files changed, 451 insertions(+), 73 deletions(-) create mode 100644 shelfzilla/apps/manga/migrations/0028_auto__add_volumecollection__add_field_volume_collection.py create mode 100644 shelfzilla/themes/bootflat/templates/manga/series/includes/volume_slim.html diff --git a/shelfzilla/apps/manga/admin.py b/shelfzilla/apps/manga/admin.py index d5c6550..bdcf3ce 100644 --- a/shelfzilla/apps/manga/admin.py +++ b/shelfzilla/apps/manga/admin.py @@ -9,7 +9,10 @@ from import_export.admin import ImportExportModelAdmin import reversion -from .models import Publisher, Series, Volume, Person, Language +from .models import ( + Publisher, Series, Volume, Person, Language, VolumeCollection, + SeriesSummary, SeriesPublisher +) ### @@ -82,6 +85,15 @@ class PublisherAdmin(ImportExportModelAdmin, reversion.VersionAdmin): admin.site.register(Publisher, PublisherAdmin) +class SeriesSummaryInline(admin.TabularInline): + model = SeriesSummary + fields = ('summary', 'language', ) + + +class SeriesPublisherInline(admin.TabularInline): + model = SeriesPublisher + fields = ('publisher', 'status', 'actual_publisher') + class SeriesAdmin(ImportExportModelAdmin, reversion.VersionAdmin): resource_class = SeriesResource list_display = ['name', 'volumes_count'] @@ -89,6 +101,7 @@ class SeriesAdmin(ImportExportModelAdmin, reversion.VersionAdmin): search_fields = ('name', ) search_filters = ('hidden', ) actions = (mark_for_review, unmark_for_review, ) + inlines = (SeriesSummaryInline, SeriesPublisherInline) suit_form_tabs = ( ('general', _('General')), @@ -127,7 +140,7 @@ admin.site.register(Series, SeriesAdmin) class VolumeAdmin(ImportExportModelAdmin, reversion.VersionAdmin): resource_class = VolumeResource # list_display_links = ('number', ) - list_display = ('series', 'publisher', 'number', 'name', 'release_date',) + list_display = ('series', 'collection', 'language', 'publisher', 'number', 'name', 'release_date',) search_fields = ('number', 'series__name', ) list_filter = ('series', 'for_review', ) # list_editable = ('series', ) @@ -207,6 +220,17 @@ admin.site.register(Person, PersonAdmin) class LanguageAdmin(ImportExportModelAdmin, reversion.VersionAdmin): list_display = ('name', 'code', 'flag_image', ) + suit_form_tabs = ( + ('general', _('General')), + ) + + fieldsets = [ + (None, { + 'classes': ('suit-tab suit-tab-general',), + 'fields': ('name', 'code', ) + }) + ] + def flag_image(self, obj): return u''.format( src=static('images/flags/{}.gif'.format(obj.code)) @@ -215,3 +239,31 @@ class LanguageAdmin(ImportExportModelAdmin, reversion.VersionAdmin): flag_image.allow_tags = True admin.site.register(Language, LanguageAdmin) + + +class VolumeCollectionAdmin(ImportExportModelAdmin, reversion.VersionAdmin): + list_display = ('name', 'series', 'default', ) + search_fields = ('name', 'series__name', ) + + suit_form_tabs = ( + ('general', _('General')), + ('review', _('Review')), + ('advanced', _('Advanced')), + ) + + fieldsets = [ + (None, { + 'classes': ('suit-tab suit-tab-general',), + 'fields': ('name', 'series', 'default') + }), + (None, { + 'classes': ('suit-tab suit-tab-review',), + 'fields': ('for_review', 'for_review_comment') + }), + (None, { + 'classes': ('suit-tab suit-tab-advanced',), + 'fields': ('hidden', ) + }), + ] + +admin.site.register(VolumeCollection, VolumeCollectionAdmin) diff --git a/shelfzilla/apps/manga/migrations/0028_auto__add_volumecollection__add_field_volume_collection.py b/shelfzilla/apps/manga/migrations/0028_auto__add_volumecollection__add_field_volume_collection.py new file mode 100644 index 0000000..cf157d8 --- /dev/null +++ b/shelfzilla/apps/manga/migrations/0028_auto__add_volumecollection__add_field_volume_collection.py @@ -0,0 +1,226 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'VolumeCollection' + db.create_table(u'manga_volumecollection', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('for_review', self.gf('django.db.models.fields.BooleanField')(default=False)), + ('for_review_comment', self.gf('django.db.models.fields.TextField')(null=True, blank=True)), + ('hidden', self.gf('django.db.models.fields.BooleanField')(default=False)), + ('name', self.gf('django.db.models.fields.CharField')(max_length=32)), + ('series', self.gf('django.db.models.fields.related.ForeignKey')(related_name='collections', to=orm['manga.Series'])), + ('default', self.gf('django.db.models.fields.BooleanField')(default=True)), + )) + db.send_create_signal(u'manga', ['VolumeCollection']) + + # Adding field 'Volume.collection' + db.add_column(u'manga_volume', 'collection', + self.gf('django.db.models.fields.related.ForeignKey')(to=orm['manga.VolumeCollection'], null=True), + keep_default=False) + + + def backwards(self, orm): + # Deleting model 'VolumeCollection' + db.delete_table(u'manga_volumecollection') + + # Deleting field 'Volume.collection' + db.delete_column(u'manga_volume', 'collection_id') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '75'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'filer.file': { + 'Meta': {'object_name': 'File'}, + '_file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'folder': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'all_files'", 'null': 'True', 'to': "orm['filer.Folder']"}), + 'has_all_mandatory_data': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'blank': 'True'}), + 'original_filename': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'owned_files'", 'null': 'True', 'to': u"orm['auth.User']"}), + 'polymorphic_ctype': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'polymorphic_filer.file_set'", 'null': 'True', 'to': u"orm['contenttypes.ContentType']"}), + 'sha1': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '40', 'blank': 'True'}), + 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}) + }, + 'filer.folder': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('parent', 'name'),)", 'object_name': 'Folder'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'filer_owned_folders'", 'null': 'True', 'to': u"orm['auth.User']"}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['filer.Folder']"}), + 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}) + }, + 'filer.image': { + 'Meta': {'object_name': 'Image', '_ormbases': ['filer.File']}, + '_height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + '_width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'author': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'date_taken': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'default_alt_text': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'default_caption': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + u'file_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['filer.File']", 'unique': 'True', 'primary_key': 'True'}), + 'must_always_publish_author_credit': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'must_always_publish_copyright': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'subject_location': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '64', 'null': 'True', 'blank': 'True'}) + }, + u'manga.language': { + 'Meta': {'ordering': "['name']", 'object_name': 'Language'}, + 'code': ('django.db.models.fields.CharField', [], {'max_length': '5'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}) + }, + u'manga.person': { + 'Meta': {'ordering': "['name']", 'object_name': 'Person'}, + 'for_review': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'for_review_comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}) + }, + u'manga.publisher': { + 'Meta': {'ordering': "['name']", 'object_name': 'Publisher'}, + 'for_review': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'for_review_comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}) + }, + u'manga.series': { + 'Meta': {'ordering': "['name']", 'object_name': 'Series'}, + 'art': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'artist_of'", 'null': 'True', 'to': u"orm['manga.Person']"}), + 'cover': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['filer.Image']", 'null': 'True', 'blank': 'True'}), + 'finished': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'folder': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['filer.Folder']", 'null': 'True', 'blank': 'True'}), + 'for_review': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'for_review_comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'original_publisher': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'original_series'", 'null': 'True', 'to': u"orm['manga.Publisher']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'open'", 'max_length': '16'}), + 'story': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'scriptwriter_of'", 'null': 'True', 'to': u"orm['manga.Person']"}), + 'summary': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'manga.seriespublisher': { + 'Meta': {'object_name': 'SeriesPublisher'}, + 'actual_publisher': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'for_review': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'for_review_comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'publisher': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'series_published'", 'to': u"orm['manga.Publisher']"}), + 'series': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'publishers'", 'to': u"orm['manga.Series']"}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'open'", 'max_length': '16'}) + }, + u'manga.seriessummary': { + 'Meta': {'unique_together': "(('series', 'language'),)", 'object_name': 'SeriesSummary'}, + 'for_review': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'for_review_comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['manga.Language']"}), + 'series': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'summaries'", 'to': u"orm['manga.Series']"}), + 'summary': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'manga.userhavevolume': { + 'Meta': {'ordering': "('volume__series__name', 'volume__number')", 'object_name': 'UserHaveVolume'}, + 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'have_volumes'", 'to': u"orm['auth.User']"}), + 'volume': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'owned_by'", 'to': u"orm['manga.Volume']"}) + }, + u'manga.userwishlistvolume': { + 'Meta': {'ordering': "('volume__series__name', 'volume__number')", 'object_name': 'UserWishlistVolume'}, + 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'wishlisted_volumes'", 'to': u"orm['auth.User']"}), + 'volume': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'wishlisted_by'", 'to': u"orm['manga.Volume']"}) + }, + u'manga.volume': { + 'Meta': {'ordering': "['series__name', 'language', 'number']", 'object_name': 'Volume'}, + 'collection': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['manga.VolumeCollection']", 'null': 'True'}), + 'cover': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['filer.Image']", 'null': 'True', 'blank': 'True'}), + 'for_review': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'for_review_comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'isbn_10': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), + 'isbn_13': ('django.db.models.fields.CharField', [], {'max_length': '13', 'null': 'True', 'blank': 'True'}), + 'language': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['manga.Language']", 'null': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'number': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'pages': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'publisher': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'volumes'", 'to': u"orm['manga.Publisher']"}), + 'release_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), + 'retail_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '5', 'decimal_places': '2', 'blank': 'True'}), + 'series': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'volumes'", 'to': u"orm['manga.Series']"}) + }, + u'manga.volumecollection': { + 'Meta': {'ordering': "['name']", 'object_name': 'VolumeCollection'}, + 'default': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'for_review': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'for_review_comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'series': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'collections'", 'to': u"orm['manga.Series']"}) + } + } + + complete_apps = ['manga'] \ No newline at end of file diff --git a/shelfzilla/apps/manga/models.py b/shelfzilla/apps/manga/models.py index 8b777bf..afac769 100644 --- a/shelfzilla/apps/manga/models.py +++ b/shelfzilla/apps/manga/models.py @@ -71,12 +71,12 @@ class Series(Model): default='open', max_length=16) original_publisher = models.ForeignKey( - Publisher, related_name='original_series', null=True) + Publisher, related_name='original_series', null=True, blank=True) art = models.ManyToManyField( - 'Person', related_name='artist_of', null=True) + 'Person', related_name='artist_of', null=True, blank=True) story = models.ManyToManyField( - 'Person', related_name='scriptwriter_of', null=True) + 'Person', related_name='scriptwriter_of', null=True, blank=True) folder = models.ForeignKey(Folder, null=True, blank=True) @@ -129,6 +129,17 @@ class Series(Model): return self._languages + def collections(self): + if not self._collections: + result = [] + queryset = self.volumes.order_by('collection__id')\ + .distinct('collection').values_list('collection') + result = VolumeCollection.objects.filter(pk__in=queryset) + + self._collections = result + + return self._collections + class Meta: ordering = ['name'] verbose_name = _('Series') @@ -166,6 +177,8 @@ class SeriesPublisher(Model): class Volume(Model): + collection = models.ForeignKey('VolumeCollection', null=True, + related_name='volumes') number = models.IntegerField(_('Number'), null=True, blank=True) name = models.CharField(_('Name'), max_length=64, null=True, blank=True) series = models.ForeignKey(Series, related_name="volumes") @@ -198,6 +211,20 @@ class Volume(Model): verbose_name_plural = _('Volumes') +class VolumeCollection(Model): + name = models.CharField(_('Name'), max_length=32) + series = models.ForeignKey('Series', related_name='collections') + default = models.BooleanField(_('Default'), default=True) + + def __unicode__(self): + return self.name + + class Meta: + ordering = ['name', ] + verbose_name = _('Collection') + verbose_name_plural = _('Collections') + + class Person(Model): name = models.CharField(_('Name'), max_length=256) slug = models.SlugField(_('Slug'), blank=True, null=True) @@ -223,6 +250,7 @@ class Language(models.Model): verbose_name = _('Language') verbose_name_plural = _('Languages') + # # RELATIONS # @@ -266,6 +294,14 @@ def series_check_filer(sender, instance, created, **kwargs): name = instance.name # Check folder + # Fix for loaddata import + if instance.folder_id: + try: + Folder.objects.get(pk=instance.folder_id) + except Folder.DoesNotExist: + instance.folder_id = None + instance.folder = None + if not instance.folder: folder, is_new = Folder.objects.get_or_create( name=name, diff --git a/shelfzilla/apps/manga/views/series.py b/shelfzilla/apps/manga/views/series.py index 1ff9ed2..509b77d 100644 --- a/shelfzilla/apps/manga/views/series.py +++ b/shelfzilla/apps/manga/views/series.py @@ -43,8 +43,17 @@ class SeriesListView(SeriesView): class SeriesDetailView(SeriesView): template = 'manga/series/detail.html' + filters = ('language', 'publisher', 'collection') def get(self, request, sid, slug=None): + vol_filters = {} + for search_filter in self.filters: + if search_filter in request.POST and request.POST[search_filter] != "0": + vol_filters['{}_id'.format(search_filter)] = \ + int(request.POST[search_filter]) + + print(vol_filters) + if slug: item = get_object_or_404(Series, pk=sid, slug=slug) else: @@ -52,8 +61,12 @@ class SeriesDetailView(SeriesView): context = { 'item': item, - # 'publisher_volumes': publisher_volumes + 'item_volumes': item.volumes.filter(**vol_filters), + 'volume_filters': vol_filters, } ctx = RequestContext(request, self.get_context(context)) return render_to_response(self.template, context_instance=ctx) + + def post(self, request, sid, slug=None): + return self.get(request, sid, slug) diff --git a/shelfzilla/locale/es/LC_MESSAGES/django.mo b/shelfzilla/locale/es/LC_MESSAGES/django.mo index 1c08957769c276df0798122144264ff24d415886..41be1ac0e744a61ab27eaadac3b9bda70d4923db 100644 GIT binary patch delta 1778 zcmYMzduYvJ9LMozc8+7`%rL{2wb@*TSdL4p*>c-zG+8ZDlnrO7!)iM;HO|CnNy;Ib z+i@u*Sw>lr#QdR|r~GX z$6pQqnf#Y0s^?te;Qx-Gxr6>NJZPTAWcpWeDBi*$_z<+eDpv=>$IVN}BNr~)se=3Pg> z@^{eSa`(9@unQIV)W%<#eK>~kPndxof)tmdTmN*F|~vj7!eW>%qIq`{u=#1!(o zW*S=HumPZd9UYsQJA(3O}O?O5`BvOaxGcXQ1X! z3$XvQXv|?CA2*@i=oo6@ljb?px4eWoco)awJ50wvsGUk@`;I4Y7Eq`D9$A&J2erc= zP=)?N6`BxbmMR&EN|=c%AQ!bj9Tal^r0qvMD2i&YBXUiDse8V@*pZ<+O+!R-ZiravCfo(Rv)B4S* zoj8C)^!ty~(1MpN;KslMPA6)?2dJ%lgo^7yo%VOAg?^X;s!`%B)LEI1nqO*`qs~gD z^}{$yzyEp~Is+}pxp0RpAa3IqP;b(Pxp))9*o)fIGOEyyZ9x5McB2a1huXmtI0xHM z>%2$h`+`voe5WxQ|KKVyCbLL#n?%opk67Os? z{8jOv&VT+&^^DmU_TM;~CG=zQg!L>&(GOrWwqiKmMTK}^?ZpK8eHekykjsqn<6*gZ zOCyniNp#{YM&ca0(BU>F1Kp@XHlgMfSa+fd*n=u?KdO+E_Wo&9yfesU8u=l#X~uB! zo2&N5Eo%oRGvPj_;xH=UIO+)|QHg$_0?nc3FItnBtirvh`*|3He$@KCwtoPf(BctwzNiMZK!`sKTdge-`!n%n}V% z=wg-niPkh!;!IQ_KGdu7qY{>)3Oa&Xcg*&y?fn|eXS^N{VJ~V&7g4V=Ig+u|>VLPVaW7JN)#!d%k0d=|?$f|^`s4eb76*_<_bP!d@OH`gQQ~?tK z8VWFp?24H|J;^*$tXV;}wHS>W_oBvqsQJ5bI~Jn~xP(g3hAN=bj`yH;_z7zL2r6D+ zj0TtaXa}ZI3ujQ3|FPo{JeC&3p>`w{^;!B*^AFnl6{uHIWyc#)^Dm+v^qw7mgoF;5 zAsXzW89^m{hpO~DD)4V)qFF!{;Nhmm6Hxs%xO_-aTkJ!{E425E?RXh#T?K0AD$%3w zzm|qhbptBU4Qn?laR_xLUZ4VevQDAS#I)@@s9sMVjw&Prd5dNw6Bl?qHpZDB6@um~0C0xDsP?YH7;`nPc%_MzVSE9(Sm{x>{K z4)cqK4$&g!ppPs%MAgB=qeZ_5o{j@t0A73z=r>Ik;S91SkTctd%y<*vWzkd|ox diff --git a/shelfzilla/locale/es/LC_MESSAGES/django.po b/shelfzilla/locale/es/LC_MESSAGES/django.po index 513f7f7..7ab1f98 100644 --- a/shelfzilla/locale/es/LC_MESSAGES/django.po +++ b/shelfzilla/locale/es/LC_MESSAGES/django.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-25 18:01+0200\n" -"PO-Revision-Date: 2014-08-25 18:01+0200\n" +"POT-Creation-Date: 2014-08-25 20:12+0200\n" +"PO-Revision-Date: 2014-08-25 20:12+0200\n" "Last-Translator: Felipe Martin \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -74,7 +74,7 @@ msgstr "Para revisión" msgid "Advanced" msgstr "Avanzado" -#: apps/manga/admin.py:80 apps/manga/models.py:134 apps/manga/models.py:135 +#: apps/manga/admin.py:80 apps/manga/models.py:145 apps/manga/models.py:146 #: themes/bootflat/templates/_layout.html:40 #: themes/bootflat/templates/homepage/home.html:94 #: themes/bootflat/templates/manga/publishers/detail.html:24 @@ -82,7 +82,7 @@ msgstr "Avanzado" msgid "Series" msgstr "Series" -#: apps/manga/admin.py:95 apps/manga/admin.py:122 apps/manga/models.py:198 +#: apps/manga/admin.py:95 apps/manga/admin.py:122 apps/manga/models.py:211 #: themes/bootflat/templates/homepage/home.html:97 #: themes/bootflat/templates/manga/publishers/detail.html:27 msgid "Volumes" @@ -102,12 +102,12 @@ msgstr "Cambiar serie de los volúmenes" msgid "Flag" msgstr "Bandera" -#: apps/manga/models.py:15 apps/manga/models.py:65 apps/manga/models.py:170 -#: apps/manga/models.py:202 apps/manga/models.py:215 +#: apps/manga/models.py:15 apps/manga/models.py:65 apps/manga/models.py:183 +#: apps/manga/models.py:215 apps/manga/models.py:229 apps/manga/models.py:242 msgid "Name" msgstr "Nombre" -#: apps/manga/models.py:16 apps/manga/models.py:66 apps/manga/models.py:203 +#: apps/manga/models.py:16 apps/manga/models.py:66 apps/manga/models.py:230 msgid "Slug" msgstr "Álias" @@ -142,78 +142,93 @@ msgstr "Cancelada" msgid "On-hold" msgstr "Parada" -#: apps/manga/models.py:68 apps/manga/models.py:141 +#: apps/manga/models.py:68 apps/manga/models.py:152 #: themes/bootflat/templates/users/profile.html:27 msgid "Summary" msgstr "Resumen" -#: apps/manga/models.py:70 apps/manga/models.py:150 +#: apps/manga/models.py:70 apps/manga/models.py:161 #: themes/bootflat/templates/manga/series/detail.html:29 msgid "Status" msgstr "Estado" -#: apps/manga/models.py:152 +#: apps/manga/models.py:163 msgid "Current publisher" msgstr "Editorial original" -#: apps/manga/models.py:169 +#: apps/manga/models.py:182 msgid "Number" msgstr "Número" -#: apps/manga/models.py:175 +#: apps/manga/models.py:188 msgid "ISBN-10" msgstr "ISBN-10" -#: apps/manga/models.py:177 +#: apps/manga/models.py:190 msgid "ISBN-13" msgstr "ISBN-13" -#: apps/manga/models.py:182 +#: apps/manga/models.py:195 msgid "Retail price" msgstr "Precio recomendado" -#: apps/manga/models.py:184 +#: apps/manga/models.py:197 msgid "Pages" msgstr "Páginas" -#: apps/manga/models.py:185 +#: apps/manga/models.py:198 msgid "Release date" msgstr "Fecha de lanzamiento" -#: apps/manga/models.py:197 +#: apps/manga/models.py:210 msgid "Volume" msgstr "Volumen" -#: apps/manga/models.py:210 +#: apps/manga/models.py:217 +msgid "Default" +msgstr "Por defecto" + +#: apps/manga/models.py:224 +#: themes/bootflat/templates/manga/series/detail.html:136 +#: themes/bootflat/templates/users/profile.html:30 +#: themes/bootflat/templates/users/profile/collection.html:4 +msgid "Collection" +msgstr "Colección" + +#: apps/manga/models.py:225 +msgid "Collections" +msgstr "Colecciones" + +#: apps/manga/models.py:237 msgid "Person" msgstr "Persona" -#: apps/manga/models.py:211 +#: apps/manga/models.py:238 msgid "Persons" msgstr "Personas" -#: apps/manga/models.py:216 +#: apps/manga/models.py:243 msgid "Code" msgstr "Código" -#: apps/manga/models.py:223 +#: apps/manga/models.py:250 #: themes/bootflat/templates/manga/series/detail.html:116 msgid "Language" msgstr "Idioma" -#: apps/manga/models.py:224 +#: apps/manga/models.py:251 msgid "Languages" msgstr "Idiomas" -#: apps/manga/models.py:233 apps/manga/models.py:250 +#: apps/manga/models.py:261 apps/manga/models.py:278 msgid "Date" msgstr "Fecha" -#: apps/manga/models.py:238 +#: apps/manga/models.py:266 msgid "have" msgstr "tiene" -#: apps/manga/models.py:255 +#: apps/manga/models.py:283 msgid "wants" msgstr "quiere" @@ -368,13 +383,13 @@ msgstr "Sin resultados" #: themes/bootflat/templates/manga/publishers/detail.html:10 #: themes/bootflat/templates/manga/series/detail.html:10 -#: themes/bootflat/templates/manga/series/includes/volume.html:48 +#: themes/bootflat/templates/manga/series/includes/volume.html:51 msgid "Edit in admin" msgstr "Editar en el admin" #: themes/bootflat/templates/manga/publishers/detail.html:20 #: themes/bootflat/templates/manga/series/detail.html:25 -#: themes/bootflat/templates/manga/series/includes/volume.html:41 +#: themes/bootflat/templates/manga/series/includes/volume.html:44 msgid "Requires review" msgstr "Requiere revisión" @@ -400,14 +415,19 @@ msgstr "Más información" #: themes/bootflat/templates/manga/series/detail.html:118 #: themes/bootflat/templates/manga/series/detail.html:128 +#: themes/bootflat/templates/manga/series/detail.html:138 msgid "All" msgstr "Todos" +#: themes/bootflat/templates/manga/series/detail.html:144 +msgid "Filter" +msgstr "Filtrar" + #: themes/bootflat/templates/manga/series/list.html:17 msgid "other" msgstr "otros" -#: themes/bootflat/templates/manga/series/includes/volume.html:38 +#: themes/bootflat/templates/manga/series/includes/volume.html:41 #, python-format msgid "%(pages)s pages" msgstr "%(pages)s páginas" @@ -420,11 +440,6 @@ msgstr "Accede al sitio" msgid "Login" msgstr "Entrar" -#: themes/bootflat/templates/users/profile.html:30 -#: themes/bootflat/templates/users/profile/collection.html:4 -msgid "Collection" -msgstr "Colección" - #: themes/bootflat/templates/users/profile.html:34 #: themes/bootflat/templates/users/profile/wishlist.html:4 msgid "Wishlist" diff --git a/shelfzilla/themes/bootflat/static/less/fixes.less b/shelfzilla/themes/bootflat/static/less/fixes.less index 0eeb5d9..7d5ff24 100644 --- a/shelfzilla/themes/bootflat/static/less/fixes.less +++ b/shelfzilla/themes/bootflat/static/less/fixes.less @@ -22,6 +22,19 @@ .volume-item { min-height: 150px !important; + &.slim { + min-height: 150px; + + .volume-content { + padding-left: 130px; + + .volume-number { + font-weight: bold; + font-size: 1.2em; + } + } + } + // Badges &:not(.user-have-it) { &:hover .badges .badge { diff --git a/shelfzilla/themes/bootflat/templates/homepage/home.html b/shelfzilla/themes/bootflat/templates/homepage/home.html index 44050aa..ab78a26 100644 --- a/shelfzilla/themes/bootflat/templates/homepage/home.html +++ b/shelfzilla/themes/bootflat/templates/homepage/home.html @@ -13,18 +13,7 @@
{% for volume in FUTURE_RELEASES %}
-
-
- -

{{ volume }}

-
-

- {{ volume.publisher }}
- {{ volume.release_date|date:'F Y' }} -

-
-
-
+ {% include "manga/series/includes/volume_slim.html" with volume=volume user=user %}
{% if forloop.counter|divisibleby:2 %}
@@ -39,18 +28,7 @@
{% for volume in LATEST_MANGA_ADDED %}
-
-
- -

{{ volume }}

-
-

- {{ volume.publisher }}
- {{ volume.release_date|date:'F Y' }} -

-
-
-
+ {% include "manga/series/includes/volume_slim.html" with volume=volume user=user %}
{% if forloop.counter|divisibleby:2 %}
diff --git a/shelfzilla/themes/bootflat/templates/manga/series/detail.html b/shelfzilla/themes/bootflat/templates/manga/series/detail.html index f996303..dcec4fe 100644 --- a/shelfzilla/themes/bootflat/templates/manga/series/detail.html +++ b/shelfzilla/themes/bootflat/templates/manga/series/detail.html @@ -109,33 +109,57 @@
{% block volume_list %}
-
+ + {% csrf_token %}
-
+
+ + +
+
- {% for volume in item.volumes_by_publisher.all %} + {% for volume in item_volumes %}
- {% include "manga/series/includes/volume.html" with volume=volume user=user show_publisher=True %} + {% include "manga/series/includes/volume.html" with volume=volume user=user show_publisher=True show_details=True %}
{% if forloop.counter|divisibleby:3 %}
diff --git a/shelfzilla/themes/bootflat/templates/manga/series/includes/volume.html b/shelfzilla/themes/bootflat/templates/manga/series/includes/volume.html index 11f63f3..9809059 100644 --- a/shelfzilla/themes/bootflat/templates/manga/series/includes/volume.html +++ b/shelfzilla/themes/bootflat/templates/manga/series/includes/volume.html @@ -1,5 +1,5 @@ {% load i18n thumbnail staticfiles %} -
+
+ {% if volume.collection and not volume.collection.default %} +
{{ volume.collection.name }}
+ {% endif %} {% if show_publisher %}
{% endif %} {% if volume.release_date %}
{{ volume.release_date|date:"F Y" }}
{% endif %} - {% if volume.pages %} -
{% blocktrans with pages=volume.pages %}{{ pages }} pages{% endblocktrans %}
+ {% if show_details %} + {% if volume.pages %} +
{% blocktrans with pages=volume.pages %}{{ pages }} pages{% endblocktrans %}
+ {% endif %} {% endif %} {% if volume.for_review and user.is_staff %} {% trans "Requires review" %} diff --git a/shelfzilla/themes/bootflat/templates/manga/series/includes/volume_slim.html b/shelfzilla/themes/bootflat/templates/manga/series/includes/volume_slim.html new file mode 100644 index 0000000..a5afc01 --- /dev/null +++ b/shelfzilla/themes/bootflat/templates/manga/series/includes/volume_slim.html @@ -0,0 +1,16 @@ +{% load thumbnail %} +
+
+ +

{{ volume }}

+
+

+ {{ volume.publisher }}
+ {% if volume.collection and not volume.collection.default %} + {{ volume.collection.name }}
+ {% endif %} + {{ volume.release_date|date:'F Y' }} +

+
+
+