在Django中对模型的特定实例的某些方法和字段进行硬编码的正确方法是什么?

时间:2016-02-21 23:07:25

标签: django django-models

我有一个网站从各个网站提取资源。其中大部分是通过RSS,但有一些是通过API,如HackerNews。我有一个显示所有Feed的ListView,所以我想保留所有这些类型的模型。

我要做的是这(不起作用):

class Feed(models.Model):
    name = models.CharField(max_length=75)
    rss = models.URLField(blank=True, null=True)

    def get_feed_data(self):
        # return data based on self.rss


class HackerNewsFeed(Feed):
    name = "Hacker News" # Doesn't work

    def get_feed_data(self):
        # Return data based on Hacker News API

this question的答案似乎说我应该简单地使用基于名称的自定义方法的Feed模型...然后我会手动将“HackerNews”输入到数据库中自动触发我的API代码。感觉有点哈哈。

实现我正在寻找的目标的最佳途径是什么?

2 个答案:

答案 0 :(得分:1)

由于Feedmodels.Model,因此您只能将模型字段指定为类参数。分配name = "Hacker News"不会对模型起作用。由于数据的形状看起来不需要根据Feed类型进行更改,因此只需按原样保留模型,然后根据{{1}实现Feed提取属性。像这样:

self.name

如果您添加太多Feed,这很快就会变得难以驾驭。我可能会将RSS提要分成一个常用的方法或类来自动处理。将以下属性添加到模型中:

# assumes a file called `feedfetcher.py` in the same 
# directory as your `models.py` file
from . import feedfetcher

class Feed(models.Model):
    name = models.CharField(max_length=75)
    rss = models.URLField(blank=True, null=True)

    def get_feed_data(self):
        return feedfetcher.fetch(self.name)


# feedfetcher.py

def fetch(name):
    if name == 'Hacker News':
        # get hacker news feed
    elif name == 'Reddit':
        # get reddit feed
    else:
        # we have no fetcher for this
        # kind of feed yet.
        raise ValueError('No fetcher for {}'.format(name))

然后,您可以查看feed_type = models.CharField(choices=(('RSS', 'RSS'), ('API', 'API')) 内的Feed类型以及RSS是否可以转到特定的RSS Feed Handler。我假设每个API都不同,因此您可以保留上面的get_feed_data方法来确定并调用每个API。

答案 1 :(得分:0)

我建议使用fixtures插入固定的Feed,然后根据get_feed_data生成name条件。

def get_feed_data(self):
    if self.name == "Hacker News":
        # Return data based on Hacker News API
    else:
        # return data based on self.rss