views:

50

answers:

3

Sorry about the title, I couldn't find the right word. I'll try my best to describe it properly.

I have a business model which needs some properties. But the properties of the business depends on what category it is.

So for example, I have a business named "XYZ" under the category "Restaurant" and a business named "ABC" under the category "Spa". I need "XYZ" to have a specific set of properties; while "ABC" has a different set of properties. Also, I need to be able to combine categories, so I just can't create a different model for each category.

I'm thinking of having a "list" in category, which "activates" the appropriate fields the business. Is that possible in Django? Or should I rethink everything?

+2  A: 

Django normally (in most deployments) maps your models into tables in a relational DB, making your desired architecture really hard to achieve. However, there's a project called django-expando which offers "A reusable Django app allowing model attributes to be assigned dynamically similar to App Engine's built-in expando class.". I don't know how well it works (its readme does mention some limitations, such as the fact that all fields are "treated as string-like" because it's "not storing types" -- so it's a bit more limited than App Engine's built-in Expando models), but something like it would seem to be the only way to achieve your desired architecture.

Alex Martelli
Thanks. I'll keep that in mid. But I'll try and re-think everything first as I don't want to resort to something like django-expando yet.
john2x
A: 

Couldn't you just create all the erroneous properties that aren't common between all businesses as nullable fields? Then, whatever properties don't apply to any specific kind of business are null. Possible categories of businesses would then just be different combinations of properties depending on what they need.

I'm probably not fully understanding your problem, so feel free to correct me. I also can't claim to be a seasoned django developer, so disregard all of this if it sounds silly to you.

junkforce
Yes that's what I'm describing in my last paragraph. I need a list in **category** that lists the properties of that category, which toggles the value of the fields in **business** which are "disabled" by default. I just don't know if it's possible in django.
john2x
A: 

Two options spring to mind. This is one I used for a business directory, using the one2one relationship I can list the whole directory in one go or just the business entries. Here the is a shortened version of the model

class Category(models.Model):
  name = models.CharField(max_length=12, unique=True)
  description = models.TextField()


class Subcategory(models.Model):
  category = models.ForeignKey(Category)
  name =  models.CharField(max_length=30, unique=True)


class Directory(models.Model):
  name = models.CharField(max_length=60)
  phone = models.CharField(max_length=15, blank=True)
  mobile = models.CharField(max_length=15, blank=True)
  etc.

class Business(Directory):
  directory = models.OneToOneField(Directory, parent_link=True, related_name="business_entries")
  cat = models.ForeignKey(Subcategory, limit_choices_to = {'category__exact': 2})
  more fields....

  def save(self):
    self.category='business'
    super(Business, self).save()

  def subcatname(self):
    return self.subcategory__name

  def full_category(self):
    return 'Business - '+self.subcategory__name


class Community(Directory):
  directory = models.OneToOneField(Directory, parent_link=True, related_name="community_entries")
  cat = models.ForeignKey(Subcategory, limit_choices_to = {'category__exact': 3})

class Tourism(Directory):
  directory = models.OneToOneField(Directory, parent_link=True, related_name="tourism_entries")
  cat = models.ForeignKey(Subcategory, limit_choices_to = {'category__exact': 4})

alternatively, you could pickle your custom data and put it into a text field. This would not be searchable however.