我有一个模型TranslationService
,它有一些字段和方法应该被每个新服务覆盖。我有三个服务:Google,Azure,Bing,这是系统中唯一的服务(我们只有一个Google服务和一个Azure服务等)。我需要执行这样的操作:TranslationService.objects.filter(service_name=service_name)
。
但是如果我使TranslationService
抽象,我不能迭代抽象类,因为它不是在DB中创建的。如果我进行继承,我应该在代码中实现重写方法的逻辑,然后通过控制台创建GoogleService
。这是唯一的方法,或者我可以通过控制台减少创建对象。
如何设计我的模型以便在translation_services中执行搜索?
class TranslationService(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
service_name = models.CharField(max_length=40)
base_url = models.CharField(max_length=255)
api_version = models.FloatField()
def get_step_translation(self, pk, lang, lesson):
pass
def create_step_translation(self, pk, lang, type):
pass
class GoogleTranslator(TranslationService):
base_url = "https://google.com"
service_name = "Google"
api_version = 1.5
def get_step_translation(self, pk, lang, lesson, **kwargs):
... some logic
def create_step_translation(self, pk, lang, type):
... some logic
答案 0 :(得分:1)
我认为模型继承是错误的方法。模型类表示数据库表,并且您的对象都存在于同一个表中,因此它们应该是相同的模型。
你可以在if语句中包含每个翻译方法的逻辑,但我理解为什么你想要抽象出来。那么您委派所有操作的单独服务类怎么样?您可以覆盖__getattr__
来设置服务并委派方法。
class GoogleTranslation(object):
def __init__(self, obj):
self.obj = obj
def get_step_translation(self, pk, lang, lesson):
print('google, {}, {}, {}'.format(pk, lang, lesson))
... logic goes here...
def create_step_translation(self, pk, lang, type):
...
class TranslationService(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
service_name = models.CharField(max_length=40)
base_url = models.CharField(max_length=255)
api_version = models.FloatField()
services = {
'google': GoogleTranslation,
'bing': BingTranslation,
}
@property
def service(self):
if not hasattr(self, '_service'):
# create a new Service object and pass it this model instance
self._service = self.services[self.service_name](self)
return self._service
def __getattr__(self, name):
if name == '_service':
raise AttributeError # the service hasn't been instantiated yet
# delegate all unknown lookups to the service object
return getattr(self.service, name)
现在,您可以通过gs = TranslationService.objects.get(service_name='google')
获取Google实例并执行gs.get_step_translation(1, '2', '3')
或其他任何操作,并且该方法调用将委托给GoogleTranslation实例。