From 44e1cf2a782bb6fe266b99238cfb79f6fa308da5 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 30 Mar 2020 13:15:49 -0700 Subject: [PATCH] Mark default edition --- fedireads/activitypub/book.py | 2 +- fedireads/connectors/openlibrary.py | 40 +- fedireads/connectors/openlibrary_languages.py | 467 ++++++++++++++++++ .../migrations/0026_auto_20200330_1943.py | 28 ++ fedireads/models/book.py | 5 +- 5 files changed, 532 insertions(+), 10 deletions(-) create mode 100644 fedireads/connectors/openlibrary_languages.py create mode 100644 fedireads/migrations/0026_auto_20200330_1943.py diff --git a/fedireads/activitypub/book.py b/fedireads/activitypub/book.py index 8d6c69931..49338ee05 100644 --- a/fedireads/activitypub/book.py +++ b/fedireads/activitypub/book.py @@ -22,7 +22,7 @@ def get_book(book): 'source_url', 'description', - 'language', + 'languages', 'series', 'series_number', 'subjects', diff --git a/fedireads/connectors/openlibrary.py b/fedireads/connectors/openlibrary.py index f6f95b6a0..f33a8a4f9 100644 --- a/fedireads/connectors/openlibrary.py +++ b/fedireads/connectors/openlibrary.py @@ -7,6 +7,7 @@ import requests from fedireads import models from .abstract_connector import AbstractConnector, SearchResult from .abstract_connector import update_from_mappings, get_date +from .openlibrary_languages import languages class Connector(AbstractConnector): @@ -84,6 +85,7 @@ class Connector(AbstractConnector): 'isbn_13': ('isbn', None), 'oclc_numbers': ('oclc_number', lambda a: a[0]), 'lccn': ('lccn', lambda a: a[0]), + 'languages': ('languages', get_languages), } book = update_from_mappings(book, data, mappings) @@ -139,14 +141,7 @@ class Connector(AbstractConnector): except ObjectDoesNotExist: book = models.Edition.objects.create(openlibrary_key=olkey) self.update_from_data(book, data) - self.set_default_edition(work) - - - def set_default_edition(self, work): - ''' pick one edition to be what gets shown by default ''' - # check for an existing default work, in which case we're done - # favor recent, hardcover, english editions - + set_default_edition(work) def get_or_create_author(self, olkey): @@ -191,9 +186,38 @@ class Connector(AbstractConnector): return [image_name, image_content] +def set_default_edition(work): + ''' pick one edition to be what gets shown by default ''' + # check for an existing default work, in which case we're done + # favor recent, hardcover, english editions + editions = models.Edition.objects.filter( + parent_work=work, + ).all() + options = [e for e in editions if 'English' in e.languages] or editions + format_prefs = { + 'hardcover': 0, + 'paperback': 1, + 'mass market paperback': 2, + } + options = sorted(options, key=lambda e: format_prefs.get(e, 3)) + options[0].default = True + options[0].save() + + def get_description(description_blob): ''' descriptions can be a string or a dict ''' if isinstance(description_blob, dict): return description_blob.get('value') return description_blob + +def get_languages(language_blob): + ''' /language/eng -> English ''' + langs = [] + for lang in language_blob: + langs.append( + languages.get(lang.get('key', ''), None) + ) + return langs + + diff --git a/fedireads/connectors/openlibrary_languages.py b/fedireads/connectors/openlibrary_languages.py new file mode 100644 index 000000000..b687f8b97 --- /dev/null +++ b/fedireads/connectors/openlibrary_languages.py @@ -0,0 +1,467 @@ +''' key lookups for openlibrary languages ''' +languages = { + '/languages/eng': 'English', + '/languages/fre': 'French', + '/languages/spa': 'Spanish', + '/languages/ger': 'German', + '/languages/rus': 'Russian', + '/languages/ita': 'Italian', + '/languages/chi': 'Chinese', + '/languages/jpn': 'Japanese', + '/languages/por': 'Portuguese', + '/languages/ara': 'Arabic', + '/languages/pol': 'Polish', + '/languages/heb': 'Hebrew', + '/languages/kor': 'Korean', + '/languages/dut': 'Dutch', + '/languages/ind': 'Indonesian', + '/languages/lat': 'Latin', + '/languages/und': 'Undetermined', + '/languages/cmn': 'Mandarin', + '/languages/hin': 'Hindi', + '/languages/swe': 'Swedish', + '/languages/dan': 'Danish', + '/languages/urd': 'Urdu', + '/languages/hun': 'Hungarian', + '/languages/cze': 'Czech', + '/languages/tur': 'Turkish', + '/languages/ukr': 'Ukrainian', + '/languages/gre': 'Greek', + '/languages/vie': 'Vietnamese', + '/languages/bul': 'Bulgarian', + '/languages/ben': 'Bengali', + '/languages/rum': 'Romanian', + '/languages/cat': 'Catalan', + '/languages/nor': 'Norwegian', + '/languages/tha': 'Thai', + '/languages/per': 'Persian', + '/languages/scr': 'Croatian', + '/languages/mul': 'Multiple languages', + '/languages/fin': 'Finnish', + '/languages/tam': 'Tamil', + '/languages/guj': 'Gujarati', + '/languages/mar': 'Marathi', + '/languages/scc': 'Serbian', + '/languages/pan': 'Panjabi', + '/languages/wel': 'Welsh', + '/languages/tel': 'Telugu', + '/languages/yid': 'Yiddish', + '/languages/kan': 'Kannada', + '/languages/slo': 'Slovak', + '/languages/san': 'Sanskrit', + '/languages/arm': 'Armenian', + '/languages/mal': 'Malayalam', + '/languages/may': 'Malay', + '/languages/bur': 'Burmese', + '/languages/slv': 'Slovenian', + '/languages/lit': 'Lithuanian', + '/languages/tib': 'Tibetan', + '/languages/lav': 'Latvian', + '/languages/est': 'Estonian', + '/languages/nep': 'Nepali', + '/languages/ori': 'Oriya', + '/languages/mon': 'Mongolian', + '/languages/alb': 'Albanian', + '/languages/iri': 'Irish', + '/languages/geo': 'Georgian', + '/languages/afr': 'Afrikaans', + '/languages/grc': 'Ancient Greek', + '/languages/mac': 'Macedonian', + '/languages/bel': 'Belarusian', + '/languages/ice': 'Icelandic', + '/languages/srp': 'Serbian', + '/languages/snh': 'Sinhalese', + '/languages/snd': 'Sindhi', + '/languages/ota': 'Turkish, Ottoman', + '/languages/kur': 'Kurdish', + '/languages/aze': 'Azerbaijani', + '/languages/pus': 'Pushto', + '/languages/amh': 'Amharic', + '/languages/gag': 'Galician', + '/languages/hrv': 'Croatian', + '/languages/sin': 'Sinhalese', + '/languages/asm': 'Assamese', + '/languages/uzb': 'Uzbek', + '/languages/gae': 'Scottish Gaelix', + '/languages/kaz': 'Kazakh', + '/languages/swa': 'Swahili', + '/languages/bos': 'Bosnian', + '/languages/glg': 'Galician ', + '/languages/baq': 'Basque', + '/languages/tgl': 'Tagalog', + '/languages/raj': 'Rajasthani', + '/languages/gle': 'Irish', + '/languages/lao': 'Lao', + '/languages/jav': 'Javanese', + '/languages/mai': 'Maithili', + '/languages/tgk': 'Tajik ', + '/languages/khm': 'Khmer', + '/languages/roh': 'Raeto-Romance', + '/languages/kok': 'Konkani ', + '/languages/sit': 'Sino-Tibetan (Other)', + '/languages/mol': 'Moldavian', + '/languages/kir': 'Kyrgyz', + '/languages/new': 'Newari', + '/languages/inc': 'Indic (Other)', + '/languages/frm': 'French, Middle (ca. 1300-1600)', + '/languages/esp': 'Esperanto', + '/languages/hau': 'Hausa', + '/languages/tag': 'Tagalog', + '/languages/tuk': 'Turkmen', + '/languages/enm': 'English, Middle (1100-1500)', + '/languages/map': 'Austronesian (Other)', + '/languages/pli': 'Pali', + '/languages/fro': 'French, Old (ca. 842-1300)', + '/languages/nic': 'Niger-Kordofanian (Other)', + '/languages/tir': 'Tigrinya', + '/languages/wen': 'Sorbian (Other)', + '/languages/bho': 'Bhojpuri', + '/languages/roa': 'Romance (Other)', + '/languages/tut': 'Altaic (Other)', + '/languages/bra': 'Braj', + '/languages/sun': 'Sundanese', + '/languages/fiu': 'Finno-Ugrian (Other)', + '/languages/far': 'Faroese', + '/languages/ban': 'Balinese', + '/languages/tar': 'Tatar', + '/languages/bak': 'Bashkir', + '/languages/tat': 'Tatar', + '/languages/chu': 'Church Slavic', + '/languages/dra': 'Dravidian (Other)', + '/languages/pra': 'Prakrit languages', + '/languages/paa': 'Papuan (Other)', + '/languages/doi': 'Dogri', + '/languages/lah': 'Lahndā', + '/languages/mni': 'Manipuri', + '/languages/yor': 'Yoruba', + '/languages/gmh': 'German, Middle High (ca. 1050-1500)', + '/languages/kas': 'Kashmiri', + '/languages/fri': 'Frisian', + '/languages/mla': 'Malagasy', + '/languages/egy': 'Egyptian', + '/languages/rom': 'Romani', + '/languages/syr': 'Syriac, Modern', + '/languages/cau': 'Caucasian (Other)', + '/languages/hbs': 'Serbo-Croatian', + '/languages/sai': 'South American Indian (Other)', + '/languages/pro': 'Provençal (to 1500)', + '/languages/cpf': 'Creoles and Pidgins, French-based (Other)', + '/languages/ang': 'English, Old (ca. 450-1100)', + '/languages/bal': 'Baluchi', + '/languages/gla': 'Scottish Gaelic', + '/languages/chv': 'Chuvash', + '/languages/kin': 'Kinyarwanda', + '/languages/zul': 'Zulu', + '/languages/sla': 'Slavic (Other)', + '/languages/som': 'Somali', + '/languages/mlt': 'Maltese', + '/languages/uig': 'Uighur', + '/languages/mlg': 'Malagasy', + '/languages/sho': 'Shona', + '/languages/lan': 'Occitan (post 1500)', + '/languages/bre': 'Breton', + '/languages/sco': 'Scots', + '/languages/sso': 'Sotho', + '/languages/myn': 'Mayan languages', + '/languages/xho': 'Xhosa', + '/languages/gem': 'Germanic (Other)', + '/languages/esk': 'Eskimo languages', + '/languages/akk': 'Akkadian', + '/languages/div': 'Maldivian', + '/languages/sah': 'Yakut', + '/languages/tsw': 'Tswana', + '/languages/nso': 'Northern Sotho', + '/languages/pap': 'Papiamento', + '/languages/bnt': 'Bantu (Other)', + '/languages/oss': 'Ossetic', + '/languages/cre': 'Cree', + '/languages/ibo': 'Igbo', + '/languages/fao': 'Faroese', + '/languages/nai': 'North American Indian (Other)', + '/languages/mag': 'Magahi', + '/languages/arc': 'Aramaic', + '/languages/epo': 'Esperanto', + '/languages/kha': 'Khasi', + '/languages/oji': 'Ojibwa', + '/languages/que': 'Quechua', + '/languages/lug': 'Ganda', + '/languages/mwr': 'Marwari', + '/languages/awa': 'Awadhi ', + '/languages/cor': 'Cornish', + '/languages/lad': 'Ladino', + '/languages/dzo': 'Dzongkha', + '/languages/cop': 'Coptic', + '/languages/nah': 'Nahuatl', + '/languages/cai': 'Central American Indian (Other)', + '/languages/phi': 'Philippine (Other)', + '/languages/moh': 'Mohawk', + '/languages/crp': 'Creoles and Pidgins (Other)', + '/languages/nya': 'Nyanja', + '/languages/wol': 'Wolof ', + '/languages/haw': 'Hawaiian', + '/languages/eth': 'Ethiopic', + '/languages/mis': 'Miscellaneous languages', + '/languages/mkh': 'Mon-Khmer (Other)', + '/languages/alg': 'Algonquian (Other)', + '/languages/nde': 'Ndebele (Zimbabwe)', + '/languages/ssa': 'Nilo-Saharan (Other)', + '/languages/chm': 'Mari', + '/languages/che': 'Chechen', + '/languages/gez': 'Ethiopic', + '/languages/ven': 'Venda', + '/languages/cam': 'Khmer', + '/languages/fur': 'Friulian', + '/languages/ful': 'Fula', + '/languages/gal': 'Oromo', + '/languages/jrb': 'Judeo-Arabic', + '/languages/bua': 'Buriat', + '/languages/ady': 'Adygei', + '/languages/bem': 'Bemba', + '/languages/kar': 'Karen languages', + '/languages/sna': 'Shona', + '/languages/twi': 'Twi', + '/languages/btk': 'Batak', + '/languages/kaa': 'Kara-Kalpak', + '/languages/kom': 'Komi', + '/languages/sot': 'Sotho', + '/languages/tso': 'Tsonga', + '/languages/cpe': 'Creoles and Pidgins, English-based (Other)', + '/languages/gua': 'Guarani', + '/languages/mao': 'Maori', + '/languages/mic': 'Micmac', + '/languages/swz': 'Swazi', + '/languages/taj': 'Tajik', + '/languages/smo': 'Samoan', + '/languages/ace': 'Achinese', + '/languages/afa': 'Afroasiatic (Other)', + '/languages/lap': 'Sami', + '/languages/min': 'Minangkabau', + '/languages/oci': 'Occitan (post 1500)', + '/languages/tsn': 'Tswana', + '/languages/pal': 'Pahlavi', + '/languages/sux': 'Sumerian', + '/languages/ewe': 'Ewe', + '/languages/him': 'Himachali', + '/languages/kaw': 'Kawi', + '/languages/lus': 'Lushai', + '/languages/ceb': 'Cebuano', + '/languages/chr': 'Cherokee', + '/languages/fil': 'Filipino', + '/languages/ndo': 'Ndonga', + '/languages/ilo': 'Iloko', + '/languages/kbd': 'Kabardian', + '/languages/orm': 'Oromo', + '/languages/dum': 'Dutch, Middle (ca. 1050-1350)', + '/languages/bam': 'Bambara', + '/languages/goh': 'Old High German', + '/languages/got': 'Gothic', + '/languages/kon': 'Kongo', + '/languages/mun': 'Munda (Other)', + '/languages/kru': 'Kurukh', + '/languages/pam': 'Pampanga', + '/languages/grn': 'Guarani', + '/languages/gaa': 'Gã', + '/languages/fry': 'Frisian', + '/languages/iba': 'Iban', + '/languages/mak': 'Makasar', + '/languages/kik': 'Kikuyu', + '/languages/cho': 'Choctaw', + '/languages/cpp': 'Creoles and Pidgins, Portuguese-based (Other)', + '/languages/dak': 'Dakota', + '/languages/udm': 'Udmurt ', + '/languages/hat': 'Haitian French Creole', + '/languages/mus': 'Creek', + '/languages/ber': 'Berber (Other)', + '/languages/hil': 'Hiligaynon', + '/languages/iro': 'Iroquoian (Other)', + '/languages/kua': 'Kuanyama', + '/languages/mno': 'Manobo languages', + '/languages/run': 'Rundi', + '/languages/sat': 'Santali', + '/languages/shn': 'Shan', + '/languages/tyv': 'Tuvinian', + '/languages/chg': 'Chagatai', + '/languages/syc': 'Syriac', + '/languages/ath': 'Athapascan (Other)', + '/languages/aym': 'Aymara', + '/languages/bug': 'Bugis', + '/languages/cel': 'Celtic (Other)', + '/languages/int': 'Interlingua (International Auxiliary Language Association)', + '/languages/xal': 'Oirat', + '/languages/ava': 'Avaric', + '/languages/son': 'Songhai', + '/languages/tah': 'Tahitian', + '/languages/tet': 'Tetum', + '/languages/ira': 'Iranian (Other)', + '/languages/kac': 'Kachin', + '/languages/nob': 'Norwegian (Bokmål)', + '/languages/vai': 'Vai', + '/languages/bik': 'Bikol', + '/languages/mos': 'Mooré', + '/languages/tig': 'Tigré', + '/languages/fat': 'Fanti', + '/languages/her': 'Herero', + '/languages/kal': 'Kalâtdlisut', + '/languages/mad': 'Madurese', + '/languages/yue': 'Cantonese', + '/languages/chn': 'Chinook jargon', + '/languages/hmn': 'Hmong', + '/languages/lin': 'Lingala', + '/languages/man': 'Mandingo', + '/languages/nds': 'Low German', + '/languages/bas': 'Basa', + '/languages/gay': 'Gayo', + '/languages/gsw': 'gsw', + '/languages/ine': 'Indo-European (Other)', + '/languages/kro': 'Kru (Other)', + '/languages/kum': 'Kumyk', + '/languages/tsi': 'Tsimshian', + '/languages/zap': 'Zapotec', + '/languages/ach': 'Acoli', + '/languages/ada': 'Adangme', + '/languages/aka': 'Akan', + '/languages/khi': 'Khoisan (Other)', + '/languages/srd': 'Sardinian', + '/languages/arn': 'Mapuche', + '/languages/dyu': 'Dyula', + '/languages/loz': 'Lozi', + '/languages/ltz': 'Luxembourgish', + '/languages/sag': 'Sango (Ubangi Creole)', + '/languages/lez': 'Lezgian', + '/languages/luo': 'Luo (Kenya and Tanzania)', + '/languages/ssw': 'Swazi ', + '/languages/krc': 'Karachay-Balkar', + '/languages/nyn': 'Nyankole', + '/languages/sal': 'Salishan languages', + '/languages/jpr': 'Judeo-Persian', + '/languages/pau': 'Palauan', + '/languages/smi': 'Sami', + '/languages/aar': 'Afar', + '/languages/abk': 'Abkhaz', + '/languages/gon': 'Gondi', + '/languages/nzi': 'Nzima', + '/languages/sam': 'Samaritan Aramaic', + '/languages/sao': 'Samoan', + '/languages/srr': 'Serer', + '/languages/apa': 'Apache languages', + '/languages/crh': 'Crimean Tatar', + '/languages/efi': 'Efik', + '/languages/iku': 'Inuktitut', + '/languages/nav': 'Navajo', + '/languages/pon': 'Ponape', + '/languages/tmh': 'Tamashek', + '/languages/aus': 'Australian languages', + '/languages/oto': 'Otomian languages', + '/languages/war': 'Waray', + '/languages/ypk': 'Yupik languages', + '/languages/ave': 'Avestan', + '/languages/cus': 'Cushitic (Other)', + '/languages/del': 'Delaware', + '/languages/fon': 'Fon', + '/languages/ina': 'Interlingua (International Auxiliary Language Association)', + '/languages/myv': 'Erzya', + '/languages/pag': 'Pangasinan', + '/languages/peo': 'Old Persian (ca. 600-400 B.C.)', + '/languages/vls': 'Flemish', + '/languages/bai': 'Bamileke languages', + '/languages/bla': 'Siksika', + '/languages/day': 'Dayak', + '/languages/men': 'Mende', + '/languages/tai': 'Tai', + '/languages/ton': 'Tongan', + '/languages/uga': 'Ugaritic', + '/languages/yao': 'Yao (Africa)', + '/languages/zza': 'Zaza', + '/languages/bin': 'Edo', + '/languages/frs': 'East Frisian', + '/languages/inh': 'Ingush', + '/languages/mah': 'Marshallese', + '/languages/sem': 'Semitic (Other)', + '/languages/art': 'Artificial (Other)', + '/languages/chy': 'Cheyenne', + '/languages/cmc': 'Chamic languages', + '/languages/dar': 'Dargwa', + '/languages/dua': 'Duala', + '/languages/elx': 'Elamite', + '/languages/fan': 'Fang', + '/languages/fij': 'Fijian', + '/languages/gil': 'Gilbertese', + '/languages/ijo': 'Ijo', + '/languages/kam': 'Kamba', + '/languages/nog': 'Nogai', + '/languages/non': 'Old Norse', + '/languages/tem': 'Temne', + '/languages/arg': 'Aragonese', + '/languages/arp': 'Arapaho', + '/languages/arw': 'Arawak', + '/languages/din': 'Dinka', + '/languages/grb': 'Grebo', + '/languages/kos': 'Kusaie', + '/languages/lub': 'Luba-Katanga', + '/languages/mnc': 'Manchu', + '/languages/nyo': 'Nyoro', + '/languages/rar': 'Rarotongan', + '/languages/sel': 'Selkup', + '/languages/tkl': 'Tokelauan', + '/languages/tog': 'Tonga (Nyasa)', + '/languages/tum': 'Tumbuka', + '/languages/alt': 'Altai', + '/languages/ase': 'American Sign Language', + '/languages/ast': 'Asturian', + '/languages/chk': 'Chuukese', + '/languages/cos': 'Corsican', + '/languages/ewo': 'Ewondo', + '/languages/gor': 'Gorontalo', + '/languages/hmo': 'Hiri Motu', + '/languages/lol': 'Mongo-Nkundu', + '/languages/lun': 'Lunda', + '/languages/mas': 'Masai', + '/languages/niu': 'Niuean', + '/languages/rup': 'Aromanian', + '/languages/sas': 'Sasak', + '/languages/sio': 'Siouan (Other)', + '/languages/sus': 'Susu', + '/languages/zun': 'Zuni', + '/languages/bat': 'Baltic (Other)', + '/languages/car': 'Carib', + '/languages/cha': 'Chamorro', + '/languages/kab': 'Kabyle', + '/languages/kau': 'Kanuri', + '/languages/kho': 'Khotanese', + '/languages/lua': 'Luba-Lulua', + '/languages/mdf': 'Moksha', + '/languages/nbl': 'Ndebele (South Africa)', + '/languages/umb': 'Umbundu', + '/languages/wak': 'Wakashan languages', + '/languages/wal': 'Wolayta', + '/languages/ale': 'Aleut', + '/languages/bis': 'Bislama', + '/languages/gba': 'Gbaya', + '/languages/glv': 'Manx', + '/languages/gul': 'Gullah', + '/languages/ipk': 'Inupiaq', + '/languages/krl': 'Karelian', + '/languages/lam': 'Lamba (Zambia and Congo)', + '/languages/sad': 'Sandawe', + '/languages/sid': 'Sidamo', + '/languages/snk': 'Soninke', + '/languages/srn': 'Sranan', + '/languages/suk': 'Sukuma', + '/languages/ter': 'Terena', + '/languages/tiv': 'Tiv', + '/languages/tli': 'Tlingit', + '/languages/tpi': 'Tok Pisin', + '/languages/tvl': 'Tuvaluan', + '/languages/yap': 'Yapese', + '/languages/eka': 'Ekajuk', + '/languages/hsb': 'Upper Sorbian', + '/languages/ido': 'Ido', + '/languages/kmb': 'Kimbundu', + '/languages/kpe': 'Kpelle', + '/languages/mwl': 'Mirandese', + '/languages/nno': 'Nynorsk', + '/languages/nub': 'Nubian languages', + '/languages/osa': 'Osage', + '/languages/sme': 'Northern Sami', + '/languages/znd': 'Zande languages', +} diff --git a/fedireads/migrations/0026_auto_20200330_1943.py b/fedireads/migrations/0026_auto_20200330_1943.py new file mode 100644 index 000000000..f9d74781d --- /dev/null +++ b/fedireads/migrations/0026_auto_20200330_1943.py @@ -0,0 +1,28 @@ +# Generated by Django 3.0.3 on 2020-03-30 19:43 + +from django.db import migrations, models +import fedireads.utils.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('fedireads', '0025_auto_20200330_0037'), + ] + + operations = [ + migrations.RemoveField( + model_name='book', + name='language', + ), + migrations.AddField( + model_name='book', + name='languages', + field=fedireads.utils.fields.ArrayField(base_field=models.CharField(max_length=255), blank=True, default=list, size=None), + ), + migrations.AddField( + model_name='edition', + name='default', + field=models.BooleanField(default=False), + ), + ] diff --git a/fedireads/models/book.py b/fedireads/models/book.py index 57cc44c8d..383098bc2 100644 --- a/fedireads/models/book.py +++ b/fedireads/models/book.py @@ -68,7 +68,9 @@ class Book(FedireadsModel): sort_title = models.CharField(max_length=255, blank=True, null=True) subtitle = models.CharField(max_length=255, blank=True, null=True) description = models.TextField(blank=True, null=True) - language = models.CharField(max_length=255, blank=True, null=True) + languages = ArrayField( + models.CharField(max_length=255), blank=True, default=list + ) series = models.CharField(max_length=255, blank=True, null=True) series_number = models.CharField(max_length=255, blank=True, null=True) subjects = ArrayField( @@ -114,6 +116,7 @@ class Work(Book): class Edition(Book): ''' an edition of a book ''' + default = models.BooleanField(default=False) # these identifiers only apply to work isbn = models.CharField(max_length=255, blank=True, null=True) oclc_number = models.CharField(max_length=255, blank=True, null=True)