mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-12-22 16:16:39 +00:00
Differentiate works and editions more clearly
This commit is contained in:
parent
44e1cf2a78
commit
f7fb9dde99
6 changed files with 109 additions and 30 deletions
|
@ -76,7 +76,7 @@ class Connector(AbstractConnector):
|
|||
return self.update_from_data(book, data)
|
||||
|
||||
|
||||
def update_from_data(self, book, data=None):
|
||||
def update_from_data(self, book, data, work=None):
|
||||
''' update a book from a json blob '''
|
||||
mappings = {
|
||||
'publish_date': ('published_date', get_date),
|
||||
|
@ -98,12 +98,13 @@ class Connector(AbstractConnector):
|
|||
book.save()
|
||||
|
||||
# this book sure as heck better be an edition
|
||||
if data.get('works'):
|
||||
key = data.get('works')[0]['key']
|
||||
key = key.split('/')[-1]
|
||||
work = self.get_or_create_book(key)
|
||||
|
||||
book.parent_work = work
|
||||
if not work:
|
||||
work = None
|
||||
if data.get('works'):
|
||||
key = data.get('works')[0]['key']
|
||||
key = key.split('/')[-1]
|
||||
work = self.get_or_create_book(key)
|
||||
book.parent_work = work
|
||||
|
||||
if isinstance(book, models.Work):
|
||||
# load editions of a work
|
||||
|
@ -128,7 +129,7 @@ class Connector(AbstractConnector):
|
|||
response = requests.get(
|
||||
'%s/works/%s/editions.json' % (self.url, work.openlibrary_key))
|
||||
edition_data = response.json()
|
||||
for data in edition_data.get('entries', []):
|
||||
for data in edition_data.get('entries', [])[:5]:
|
||||
try:
|
||||
olkey = data['key'].split('/')[-1]
|
||||
except KeyError:
|
||||
|
@ -140,7 +141,7 @@ class Connector(AbstractConnector):
|
|||
continue
|
||||
except ObjectDoesNotExist:
|
||||
book = models.Edition.objects.create(openlibrary_key=olkey)
|
||||
self.update_from_data(book, data)
|
||||
self.update_from_data(book, data, work=work)
|
||||
set_default_edition(work)
|
||||
|
||||
|
||||
|
|
67
fedireads/migrations/0027_auto_20200330_2042.py
Normal file
67
fedireads/migrations/0027_auto_20200330_2042.py
Normal file
|
@ -0,0 +1,67 @@
|
|||
# Generated by Django 3.0.3 on 2020-03-30 20:42
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('fedireads', '0026_auto_20200330_1943'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='book',
|
||||
name='parent_work',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='book',
|
||||
name='shelves',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='edition',
|
||||
name='parent_work',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='fedireads.Work'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='edition',
|
||||
name='shelves',
|
||||
field=models.ManyToManyField(through='fedireads.ShelfBook', to='fedireads.Shelf'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='comment',
|
||||
name='book',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='fedireads.Edition'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='notification',
|
||||
name='related_book',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='fedireads.Edition'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='review',
|
||||
name='book',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='fedireads.Edition'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='shelf',
|
||||
name='books',
|
||||
field=models.ManyToManyField(through='fedireads.ShelfBook', to='fedireads.Edition'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='shelfbook',
|
||||
name='book',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='fedireads.Edition'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='status',
|
||||
name='mention_books',
|
||||
field=models.ManyToManyField(related_name='mention_book', to='fedireads.Edition'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='tag',
|
||||
name='book',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='fedireads.Edition'),
|
||||
),
|
||||
]
|
|
@ -84,13 +84,6 @@ class Book(FedireadsModel):
|
|||
cover = models.ImageField(upload_to='covers/', blank=True, null=True)
|
||||
first_published_date = models.DateTimeField(blank=True, null=True)
|
||||
published_date = models.DateTimeField(blank=True, null=True)
|
||||
shelves = models.ManyToManyField(
|
||||
'Shelf',
|
||||
symmetrical=False,
|
||||
through='ShelfBook',
|
||||
through_fields=('book', 'shelf')
|
||||
)
|
||||
parent_work = models.ForeignKey('Work', on_delete=models.PROTECT, null=True)
|
||||
objects = InheritanceManager()
|
||||
|
||||
@property
|
||||
|
@ -100,6 +93,12 @@ class Book(FedireadsModel):
|
|||
model_name = type(self).__name__.lower()
|
||||
return '%s/%s/%s' % (base_path, model_name, self.openlibrary_key)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
''' can't be abstract for query reasons, but you shouldn't USE it '''
|
||||
if not isinstance(self, Edition) and not isinstance(self, Work):
|
||||
raise ValueError('Books should be added as Editions or Works')
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return "<{} key={!r} title={!r}>".format(
|
||||
self.__class__,
|
||||
|
@ -125,6 +124,13 @@ class Edition(Book):
|
|||
publishers = ArrayField(
|
||||
models.CharField(max_length=255), blank=True, default=list
|
||||
)
|
||||
shelves = models.ManyToManyField(
|
||||
'Shelf',
|
||||
symmetrical=False,
|
||||
through='ShelfBook',
|
||||
through_fields=('book', 'shelf')
|
||||
)
|
||||
parent_work = models.ForeignKey('Work', on_delete=models.PROTECT, null=True)
|
||||
|
||||
|
||||
class Author(FedireadsModel):
|
||||
|
|
|
@ -10,7 +10,7 @@ class Shelf(FedireadsModel):
|
|||
user = models.ForeignKey('User', on_delete=models.PROTECT)
|
||||
editable = models.BooleanField(default=True)
|
||||
books = models.ManyToManyField(
|
||||
'Book',
|
||||
'Edition',
|
||||
symmetrical=False,
|
||||
through='ShelfBook',
|
||||
through_fields=('shelf', 'book')
|
||||
|
@ -29,7 +29,7 @@ class Shelf(FedireadsModel):
|
|||
|
||||
class ShelfBook(FedireadsModel):
|
||||
# many to many join table for books and shelves
|
||||
book = models.ForeignKey('Book', on_delete=models.PROTECT)
|
||||
book = models.ForeignKey('Edition', on_delete=models.PROTECT)
|
||||
shelf = models.ForeignKey('Shelf', on_delete=models.PROTECT)
|
||||
added_by = models.ForeignKey(
|
||||
'User',
|
||||
|
|
|
@ -15,7 +15,7 @@ class Status(FedireadsModel):
|
|||
status_type = models.CharField(max_length=255, default='Note')
|
||||
content = models.TextField(blank=True, null=True)
|
||||
mention_users = models.ManyToManyField('User', related_name='mention_user')
|
||||
mention_books = models.ManyToManyField('Book', related_name='mention_book')
|
||||
mention_books = models.ManyToManyField('Edition', related_name='mention_book')
|
||||
activity_type = models.CharField(max_length=255, default='Note')
|
||||
local = models.BooleanField(default=True)
|
||||
privacy = models.CharField(max_length=255, default='public')
|
||||
|
@ -49,7 +49,7 @@ class Status(FedireadsModel):
|
|||
class Comment(Status):
|
||||
''' like a review but without a rating and transient '''
|
||||
name = models.CharField(max_length=255)
|
||||
book = models.ForeignKey('Book', on_delete=models.PROTECT)
|
||||
book = models.ForeignKey('Edition', on_delete=models.PROTECT)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.status_type = 'Comment'
|
||||
|
@ -60,7 +60,7 @@ class Comment(Status):
|
|||
class Review(Status):
|
||||
''' a book review '''
|
||||
name = models.CharField(max_length=255)
|
||||
book = models.ForeignKey('Book', on_delete=models.PROTECT)
|
||||
book = models.ForeignKey('Edition', on_delete=models.PROTECT)
|
||||
rating = models.IntegerField(
|
||||
default=0,
|
||||
validators=[MinValueValidator(0), MaxValueValidator(5)]
|
||||
|
@ -92,7 +92,7 @@ class Favorite(FedireadsModel):
|
|||
class Tag(FedireadsModel):
|
||||
''' freeform tags for books '''
|
||||
user = models.ForeignKey('User', on_delete=models.PROTECT)
|
||||
book = models.ForeignKey('Book', on_delete=models.PROTECT)
|
||||
book = models.ForeignKey('Edition', on_delete=models.PROTECT)
|
||||
name = models.CharField(max_length=100)
|
||||
identifier = models.CharField(max_length=100)
|
||||
|
||||
|
@ -113,7 +113,7 @@ class Notification(FedireadsModel):
|
|||
''' you've been tagged, liked, followed, etc '''
|
||||
user = models.ForeignKey('User', on_delete=models.PROTECT)
|
||||
related_book = models.ForeignKey(
|
||||
'Book', on_delete=models.PROTECT, null=True)
|
||||
'Edition', on_delete=models.PROTECT, null=True)
|
||||
related_user = models.ForeignKey(
|
||||
'User',
|
||||
on_delete=models.PROTECT, null=True, related_name='related_user')
|
||||
|
|
|
@ -55,14 +55,14 @@ def home_tab(request, tab):
|
|||
shelves.append({
|
||||
'name': 'Recently added',
|
||||
'identifier': None,
|
||||
'books': models.Book.objects.order_by(
|
||||
'books': models.Edition.objects.order_by(
|
||||
'-created_date'
|
||||
)[:6 - size],
|
||||
'count': 6 - size,
|
||||
})
|
||||
|
||||
# allows us to check if a user has shelved a book
|
||||
user_books = models.Book.objects.filter(shelves__user=request.user).all()
|
||||
user_books = models.Edition.objects.filter(shelves__user=request.user).all()
|
||||
|
||||
# status updates for your follow network
|
||||
following = models.User.objects.filter(
|
||||
|
@ -322,11 +322,16 @@ def book_page(request, book_identifier, tab='friends'):
|
|||
return JsonResponse(activitypub.get_book(book))
|
||||
|
||||
if isinstance(book, models.Work):
|
||||
book_reviews = models.Review.objects.filter(
|
||||
Q(book=book) | Q(book__parent_work=book),
|
||||
)
|
||||
else:
|
||||
book_reviews = models.Review.objects.filter(book=book)
|
||||
book = models.Edition.objects.filter(
|
||||
parent_work=book,
|
||||
default=True
|
||||
).first()
|
||||
if not book:
|
||||
book = models.Edition.objects.filter(
|
||||
parent_work=book,
|
||||
).first()
|
||||
|
||||
book_reviews = models.Review.objects.filter(book=book)
|
||||
|
||||
if request.user.is_authenticated:
|
||||
user_reviews = book_reviews.filter(
|
||||
|
|
Loading…
Reference in a new issue