2012-02-13 7 views
4

Я создаю приложение, в котором пользователь может подписаться/следовать различным аспектам сайта.Django ForeignKey из нескольких объектов

Я строю таблицу, в которой будут записываться все эти подписки. Мой первоначальный инстинкт состоит в том, чтобы сделать одну таблицу подписки, в которой будет указано все, на что подписано. Вот как я планирую сейчас:

class SubscriptionTypeCode(object): 
    CITY = '1' 
    REGION = '2' 
    COUNTRY = '3' 
    USER = '4' 

SUBSCRIPTION_TYPE_CHOICES = (
    (SubscriptionTypeCode.CITY, 'City'), 
    (SubscriptionTypeCode.REGION, 'Region'), 
    (SubscriptionTypeCode.COUNTRY, 'Country'), 
    (SubscriptionTypeCode.USER, 'User'), 
) 
class Subscription(models.Model): 
    subscriber = models.ForeignKey(User, related_name="subscriber") 
    subscription_type = models.CharField(max_length=4, choices=SUBSCRIPTION_TYPE_CHOICES) 
    subscription_to_user = models.ForeignKey(User, related_name="subscription_to_user", null=True, blank=True) 
    subscription_to_city = models.ForeignKey(City, null=True, blank=True) 
    subscription_to_country = models.ForeignKey(Country, null=True, blank=True) 
    subscription_to_region = models.ForeignKey(Region, null=True, blank=True) 
    created = models.DateTimeField(db_index=True, auto_now_add=True) 
    cancelled = models.DateTimeField(null=True, blank=True) 

Это должно работать, но я задаюсь вопросом, если это самый эффективный способ сделать это. Каждая строка будет иметь идентификатор абонента, затем выбор типа, а затем, в зависимости от этого, один из столбцов subscription_to будет иметь посторонний объект.

Это работает, но в логике требуется много утверждений if/else. Например

def create_subscription(request, subscription_type, subscription_id): 
    subscription = Subscription.create(
     subscriber = request.user, 
     subscription_type = subscription_type, 
    ) 
    if subscription_type == SubscriptionTypeCode.REGION: 
     region = get_region(subscription_id) 
     subscription.subscription_to_region = region 

    elif subscription_type == SubscriptionTypeCode.CITY: 
     city = get_city(subscription_id) 
     subscription.subscription_to_city = city 

    elif subscription_type == SubscriptionTypeCode.COUNTRY: 
     country = get_country(subscription_id) 
     subscription.subscription_to_country = country 

    elif subscription_type == SubscriptionTypeCode.USER: 
     user = get_user(subscription_id) 
     subscription.subscription_to_user = user 

    subscription.save() 
    return subscription 

Любые мысли о том, как это упростить? Или это хорошо?

ответ

3

Вы можете использовать generic foreign keys (с одним subscription_to поля) или model inheritance (с подклассами Subscription для различных типов подписки, которые, по крайней мере, позволят вам структурировать ваш код лучше).

Смежные вопросы