forked from mirrors/bookwyrm
Merge pull request #421 from mouse-reeve/reverse-set-many-to-many
Fixes celery tasks expanding data not setting many to many fields
This commit is contained in:
commit
f6f075fac6
2 changed files with 30 additions and 24 deletions
|
@ -111,15 +111,10 @@ class ActivityObject:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
model_field = getattr(model, model_field_name)
|
model_field = getattr(model, model_field_name)
|
||||||
try:
|
# creating a Work, model_field is 'editions'
|
||||||
# this is for one to many
|
# creating a User, model field is 'key_pair'
|
||||||
related_model = model_field.field.model
|
related_model = model_field.field.model
|
||||||
related_field_name = model_field.field.name
|
related_field_name = model_field.field.name
|
||||||
except AttributeError:
|
|
||||||
# it's a one to one or foreign key
|
|
||||||
related_model = model_field.related.related_model
|
|
||||||
related_field_name = model_field.related.related_name
|
|
||||||
values = [values]
|
|
||||||
|
|
||||||
for item in values:
|
for item in values:
|
||||||
set_related_field.delay(
|
set_related_field.delay(
|
||||||
|
@ -142,8 +137,8 @@ class ActivityObject:
|
||||||
@app.task
|
@app.task
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def set_related_field(
|
def set_related_field(
|
||||||
model_name, origin_model_name,
|
model_name, origin_model_name, related_field_name,
|
||||||
related_field_name, related_remote_id, data):
|
related_remote_id, data):
|
||||||
''' load reverse related fields (editions, attachments) without blocking '''
|
''' load reverse related fields (editions, attachments) without blocking '''
|
||||||
model = apps.get_model('bookwyrm.%s' % model_name, require_ready=True)
|
model = apps.get_model('bookwyrm.%s' % model_name, require_ready=True)
|
||||||
origin_model = apps.get_model(
|
origin_model = apps.get_model(
|
||||||
|
@ -153,21 +148,34 @@ def set_related_field(
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
if isinstance(data, str):
|
if isinstance(data, str):
|
||||||
item = resolve_remote_id(model, data, save=False)
|
existing = model.find_existing_by_remote_id(data)
|
||||||
|
if existing:
|
||||||
|
data = existing.to_activity()
|
||||||
else:
|
else:
|
||||||
# look for a match based on all the available data
|
data = get_data(data)
|
||||||
item = model.find_existing(data)
|
activity = model.activity_serializer(**data)
|
||||||
if not item:
|
|
||||||
# create a new model instance
|
|
||||||
item = model.activity_serializer(**data)
|
|
||||||
item = item.to_model(model, save=False)
|
|
||||||
# this must exist because it's the object that triggered this function
|
# this must exist because it's the object that triggered this function
|
||||||
instance = origin_model.find_existing_by_remote_id(related_remote_id)
|
instance = origin_model.find_existing_by_remote_id(related_remote_id)
|
||||||
if not instance:
|
if not instance:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'Invalid related remote id: %s' % related_remote_id)
|
'Invalid related remote id: %s' % related_remote_id)
|
||||||
|
|
||||||
# edition.parent_work = instance, for example
|
# set the origin's remote id on the activity so it will be there when
|
||||||
|
# the model instance is created
|
||||||
|
# edition.parentWork = instance, for example
|
||||||
|
model_field = getattr(model, related_field_name)
|
||||||
|
if hasattr(model_field, 'activitypub_field'):
|
||||||
|
setattr(
|
||||||
|
activity,
|
||||||
|
getattr(model_field, 'activitypub_field'),
|
||||||
|
instance.remote_id
|
||||||
|
)
|
||||||
|
item = activity.to_model(model)
|
||||||
|
|
||||||
|
# if the related field isn't serialized (attachments on Status), then
|
||||||
|
# we have to set it post-creation
|
||||||
|
if not hasattr(model_field, 'activitypub_field'):
|
||||||
setattr(item, related_field_name, instance)
|
setattr(item, related_field_name, instance)
|
||||||
item.save()
|
item.save()
|
||||||
|
|
||||||
|
|
|
@ -59,9 +59,7 @@ class Book(BookDataModel):
|
||||||
subject_places = fields.ArrayField(
|
subject_places = fields.ArrayField(
|
||||||
models.CharField(max_length=255), blank=True, null=True, default=list
|
models.CharField(max_length=255), blank=True, null=True, default=list
|
||||||
)
|
)
|
||||||
# TODO: include an annotation about the type of authorship (ie, translator)
|
|
||||||
authors = fields.ManyToManyField('Author')
|
authors = fields.ManyToManyField('Author')
|
||||||
# preformatted authorship string for search and easier display
|
|
||||||
cover = fields.ImageField(
|
cover = fields.ImageField(
|
||||||
upload_to='covers/', blank=True, null=True, alt_field='alt_text')
|
upload_to='covers/', blank=True, null=True, alt_field='alt_text')
|
||||||
first_published_date = fields.DateTimeField(blank=True, null=True)
|
first_published_date = fields.DateTimeField(blank=True, null=True)
|
||||||
|
|
Loading…
Reference in a new issue