0

I have an Article table

class Article(models.Model):
    """
    Model to keep articles
    """

    ext_id = models.UUIDField(primary_key=True, db_index=True, default=uuid.uuid4, editable=False)
    title = models.CharField(max_length=255, unique=True, db_index=True)
    content = models.TextField()
    summary = models.TextField()
    img_url = models.URLField(max_length=200)
    author = models.CharField(max_length=50, blank=True, null=True)
    sport  = models.ForeignKey('Sport')
    posted_on= models.DateTimeField()
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return "%s by %s" % (self.title, self.author)

A table where I store articles liked by a user :

class LikedArticle(models.Model):

    """
    Articles that a user wants to read 
    """

    ext_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    article = models.ForeignKey(Article)
    profile = models.ForeignKey(Profile)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

and unliked :

class UnlikedLikedArticle(models.Model):

    """
    Articles that a user does not want to read 
    """

    ext_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    article = models.ForeignKey(Article)
    profile = models.ForeignKey(Profile)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

Now here, both the tables liked and unliked, are structurally the same. I find it better to store it like this instead of storing say a bool field called is_liked because I exactly know what data I am storing. So I don't have to query a huge set of articles when I know that I am only interested in LikedArticle. Is this the correct approach ? I am only confused because structurally they look the same and something doesn't feel right about this design.

Deepankar Bajpeyi
  • 5,661
  • 11
  • 44
  • 64

3 Answers3

1

the best approach that i recommend is to use one table and add is_liked field. (and add index to this field, so you get high performance queries)

but if still you want to use your approach with 2 table, then you need to fix your design.

use one abstract model that has all fields, and the Like and Unlike tables inherit from the abstract model

class ActionOnArticle(Model):

    your fields here.. 

    class Meta:
        abstract = True

class LikedArticle(ActionOnArticle):


class UnLikedArticle(ActionOnArticle):
Eyal Ch
  • 9,552
  • 5
  • 44
  • 54
1

I think is_liked is not a good option if you want to save other information per profile, like that: who liked what and when and so on. If you want to lose those info so my suggestion is to use many to many relationship and the article model will be something like that:

class Article(models.Model):
   """
    Model to keep articles
   """

    ext_id = models.UUIDField(primary_key=True, db_index=True, default=uuid.uuid4, editable=False)
    title = models.CharField(max_length=255, unique=True, db_index=True)
    content = models.TextField()
    summary = models.TextField()
    img_url = models.URLField(max_length=200)
    author = models.CharField(max_length=50, blank=True, null=True)
    sport  = models.ForeignKey('Sport')
    posted_on= models.DateTimeField()
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    likes = models.ManyToManyField(Profile)
    unlikes = models.ManyToManyField(Profile)

def __unicode__(self):
    return "%s by %s" % (self.title, self.author)

https://docs.djangoproject.com/en/1.8/topics/db/examples/many_to_many/

While if you want to save the info mentioned at the beginning of my reply, I think @Eyal answer is fine

Ahmed Hosny
  • 1,162
  • 10
  • 21
0

I'd use the "is_liked" BooleanField and filter on it to just get the liked or disliked articles. Filtering on a BooleanField (add db_index=True on the field options) will be extremely fast with any decent database so you are very unlikely to get a noticable performance increase using separate tables even if they were huge.

sean
  • 741
  • 2
  • 7
  • 14