Вот как бы я это сделал.Взглянув на то, как работает класс ToOneField
, вы заметите, что пара методов гидрат / дегидрат заботится о получении и настройке фактического связанного экземпляра.Подклассифицируя ToOneField
и переопределяя эти два метода, вы можете получить преимущество автоматизированной обработки ресурсов Tastypie без фактического внешнего ключа.
(я имею в виду ToOneField
вместо ToManyField
, потому что в вашеммодель, данная RevisionToApply
может указывать только на одну ревизию, кажется.)
Это будет выглядеть примерно так:
class NoForeignKeyToOneField(ToOneField):
def dehydrate(self, bundle):
# Look up the related object manually
try:
obj_key = getattr(bundle.obj, self.attribute)
###
# Get the revision object here. If you want to make it generic,
# maybe pass a callable on __init__ that can be invoked here
###
foreign_obj = revision_object
except ObjectDoesNotExist:
foreign_obj = None
# The rest remains the same
if not foreign_obj:
if not self.null:
raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (bundle.obj, self.attribute))
return None
self.fk_resource = self.get_related_resource(foreign_obj)
fk_bundle = Bundle(obj=foreign_obj, request=bundle.request)
return self.dehydrate_related(fk_bundle, self.fk_resource)
def hydrate(self, bundle):
value = super(NoForeignKeyToOneField, self).hydrate(bundle)
if value is None:
return value
# Here, don't return the full resource, only the primary key
related_resource = self.build_related_resource(value, request=bundle.request)
return related_resource.pk
А затем используйте этот тип поля в вашем ресурсе, а нечем основной ToOneField
.Я не проверял это, но я верю, что подход здравый, простой, и он сделает работу.