I have a model built like this
class ApiPartner(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=30, verbose_name=_('Name'))
api_key = models.CharField(max_length=50, verbose_name=_('API key'), null=True)
secret_key = models.CharField(max_length=50, verbose_name=_('Secret key'), null=True)
client_key = models.CharField(max_length=50, verbose_name=_('Client key'), null=True)
endpoint = models.CharField(max_length=50, verbose_name=_('Endpoint'), null=True)
logo = models.ImageField(upload_to='logos/', null=True)
evey API partner has its own method to retrieve data, for example
def get_youtube_posts(endpoint,api_key):
results=list(requests.get(endpoint '?key=' api_key).json())
return results[0:50]
def get_instagram_posts(endpoint,api_key,secret_key):
return requests.get(endpoint '?key=' api_key '&secret=' secret_key)
the question is: how do i assign the 'get_posts' function to the model so i can call a generic ApiPartner.get_posts()
and it will retrieve the posts using the given function?
I'm thinking about like a models.FunctionField but i know that doesn't exist.
I think this is more a logical problem than a technical one but i can't find a way. Thank you
CodePudding user response:
Maybe I'm understanding the question wrong; but you can just assign it as a property on the model class:
class MyModel(models.Model):
fields...
@property
def youtube_posts(self):
results=list(requests.get(self.endpoint '?key=' self.api_key).json())
return results[0:50]
@property
def instagram_posts(self):
return requests.get(self.endpoint '?key=' self.api_key '&secret=' self.secret_key)
Then you can call it with the instance of your model.
mymodel = MyModel.objects.all().first()
youtube_posts = mymodel.youtube_posts
# or
instagram_posts = mymodel.instagram_posts
But this will only return one or the other since your models are based on one specific endpoint. To create a more generic method on the model, use the above methods, plus this:
@property
def platform_posts(self)
if "instagram" in self.endpoint:
return self.instagram_posts
elif "youtube" in self.endpoint:
return self.youtube_posts
... You get the gist.