Efficient Django model for blog post I'm currently trying to create a travel blog using Django whereby users will be able to create a travel plan with the following features:


Each user can create a travel event based on the start date and end date for specific locations, with some meaningful description
He/She can also upload images for associated with specific travel event
A travel plan can consists of multiple travel events of various date


Will the following model be an efficient design?

    from django.db import models
    import datetime

    from __future__ import unicode_literals
    from django.core.urlresolvers import reverse
    from django.core.exceptions import ValidationError
    from django.utils import timezone
    from django.utils.translation import ugettext_lazy as _
    from django.conf import settings
    from django.utils.encoding import python_2_unicode_compatible

    # Create your models here.

    auth_user_model = getattr(settings, "AUTH_USER_MODEL", "auth.User")

    class Entry(models.Model):
        title = models.CharField(max_length=100)
        start_date = models.DateTimeField(_("start date"))
        end_date = models.DateTimeField(_("end date"))
        description = models.TextField(_("description"))
        accomodation = models.TextField(_("accomodation"))
        location = models.TextField(_("location"))
        images = models.ManyToManyField("Image", verbose_name=_("images"), blank=True, null=True)
        post_entry = models.ForeignKey(Post_Entry)

    class Post_Entry(models.Model):
        author = models.ForeignKey(User)
        created_by = models.ForeignKey(auth_user_model, verbose_name=_("created by"))
        categories = models.ManyToManyField("Category", verbose_name=_("categories"), blank=True)
        created_on = models.DateTimeField(auto_now_add = True)  
        remarks = models.TextField(_("Remarks"))

    @python_2_unicode_compatible
    class Image(models.Model):
        title = models.CharField(max_length=60, blank=True, null=True)
        image = models.FileField(upload_to="images/")
        width = models.IntegerField(blank=True, null=True)
        height = models.IntegerField(blank=True, null=True)

        def __str__(self):
            return self.image.name

    @python_2_unicode_compatible
    class Category(models.Model):
        title = models.CharField(_('title'), max_length=255)

        def __str__(self):
            return self.title

        class Meta:
            verbose_name_plural = 'Categories'
Before thinking about making it efficient, I would worry more about making it clear, natural, intuitive. In your description you mention the notions "travel plan" and "travel event", and it's not easy to find the correspondence in the code. It would be easier to understand the overall design if the connection was more clear, for example if you had classes like TravelPlan and TravelEvent.

There are some other minor problems too with the code.



Drop this comment:


# Create your models here.



(I know it's automatically generated by Django, you're supposed to delete it after you created some models, which you already did.)



These imports are unused, so it's better to delete them:


import datetime

from django.core.urlresolvers import reverse
from django.core.exceptions import ValidationError
from django.utils import timezone





According to PEP8, you should put 2 blank lines before each class definition.

Also, classes in Python should be named CamelCase without underscores,
which is violated by Post_Entry.



It's good to declare closely related fields next to one another.
For example here:


    created_by = models.ForeignKey(auth_user_model, verbose_name=_("created by"))
    categories = models.ManyToManyField("Category", verbose_name=_("categories"), blank=True)
    created_on = models.DateTimeField(auto_now_add = True)



It would be better to move categories out from between created_by and created_on.