from django.db import models
# Import the User model, so User is available to subsequent code that makes use of it.
from django.contrib.auth.models import User

# http://stackoverflow.com/questions/30471812/global-name-reverse-is-not-defined
from django.core.urlresolvers import reverse
from datetime import date # Used in 'is_overdue' function

# Create your models here.
class Genre(models.Model):
    """
    Model representing a book genre (e.g. Science Fiction, Non Fiction). 
    """

    name = models.CharField(max_length=200, help_text="Enter a book genre (e.g. Science Fiction, French Poetry etc.)")

    def __str__(self):
        """
        String for representing the Model object (in Admin site etc.)
        """

        return self.name


# =============================================================================

class Language(models.Model):
    """
    Model representing the language a book is written in (e.g. English, German, Chinese). 
    """
    # NOTE: A language can be associated to MANY books.

    name = models.CharField(max_length=200, help_text="Enter the language the book is written in.")

    def __str__(self):
        """
        String for representing the model object (in Admin site etc.)
        """

        return self.name




# =============================================================================

class Book(models.Model):
    """
    Model representing a book (but not a specific copy of a book).
    """

    title = models.CharField(max_length=200)
    author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
    # Foreign Key used because book can only have one author, but authors can have multiple books. 
    # NOTE: This is not true, somtimes a book is written by several authors. 
    #       => Should be ManyToManyField intead.
    # Author as a string (for now) rather than object because it hasn't been declared yet in the file.
    summary = models.TextField(max_length=1000, help_text="Enter a brief description of the book")
    isbn    = models.CharField('ISBN', max_length=13, help_text='13 Character <a href="https://www.isbn-international.org/content/what-isbn">ISBN number</a>')
    genre   = models.ManyToManyField(Genre, help_text="Select a genre for this book.")
    # ManyToManyField used because genre can contain many books. Books can cover many genres. 
    # Genre class has already been defined, so we can specify the object above. 

    # A book is associated with ONE and only ONE langage => ForeignKey
    language = models.ForeignKey('Language', on_delete=models.SET_NULL, null=True)

    def __str__(self):
        """
        String for representing the Model object. 
        """
        
        return self.title

    # https://docs.djangoproject.com/en/1.8/ref/urlresolvers/#reverse
    def get_absolute_url(self):
        """
        Returns the url to access a particular book instance. 
        """
        return reverse('book-detail', args=[str(self.id)])  
        # Returns an URL that can be used to access a detail record for this model 
        # (for this to work we will have to 
        # -- Define a URL mapping that has the name 'book-detail' (name='book-detail')
        # -- Define an associated view.
        # -- Define an associated template.


    def display_genre(self):
        """
        Creates a string for the Genre. This is required to display genre in Admin.
        """
         
        # Get first 3 genres and join to a string.
        return ', '.join([ genre.name for genre in self.genre.all()[:3] ])

    display_genre.short_description = 'Genre'



# =============================================================================

import uuid # Required for unique book instances.

class BookInstance(models.Model):
    """
    Model representing a specific copy of a book (i.e. that can be borrowed from the library). 
    """

    id = models.UUIDField(
        primary_key=True, 
        default=uuid.uuid4, 
        help_text="Unique ID for this particular book accross whole library.",
    )

    # ForeignKey (one-to many) 
    book = models.ForeignKey(
        'Book',
        on_delete=models.SET_NULL,
        null=True,
    )

    imprint = models.CharField(max_length=200)

    due_back = models.DateField(null=True, blank=True)
    # Set to Null when the book is available, because then there is no due date.

    LOAN_STATUS = (
        ('d', 'Maintenance'),
        ('o', 'On loan'),
        ('a', 'Available'),
        ('r', 'Reserved'),
    )

    status = models.CharField(
        max_length=1, 
        choices=LOAN_STATUS, 
        blank=True,  # If no value given, the default value is used.
        default='d', # Because a book will initially be created unavailable before being stocked on the shelve.
        help_text="Book Availability",
    )

    borrower = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
    )

    # Add a property that we can call from our templates
    # from datetime import date # Called at the top of the file
    @property
    def is_overdue(self):
        if date.today() > self.due_back:
            return True
        return False


    class Meta:
        ordering = ["due_back"]

        # Assign permission to "Librarian" group in the Admin site.
        permissions = (
            ("can_mark_returned", "Set book as returned"),
            ("can_renew",         "Renew book on loan"),
        )
        # Next Permission Steps:
        # =========================
        # NOTE 1: After running the migrations, the new permissions will be selectable 
        #         in the Admin for each group: http://127.0.0.1:8000/admin/auth/group/
        # NOTE 2: Templates: Check for permission with {{ perms.catalog.can_mark_returned }}
        # NOTE 3: Views
        # - Class-based: 
        # --------------------------
        #   from django.contrib.auth.mixins import PermissionRequiredMixin
        #   class MyView(PermissionRequiredMixin, View):
        #       permission_required = ('catalog.can_mark_returned', 'catalog.can_edit')
        # - Function-based:
        # --------------------------
        #   from django.contrib.auth.decorators import permission_required
        #   @permission_required('catalog.can_mark_returned')
        #   @permission_required('catalog.can_edit')
        #   def my_view(request):
        # NOTE: Testing for  a permission also tests for authentication.

    
    def __str__(self):
        """
        String for representing the Model object. 
        """

        return '%s (%s)' % (self.id, self.book.title)


# =============================================================================

class Author(models.Model):
    """
    Model representing the author.
    """

    first_name = models.CharField(max_length=100)
    last_name  = models.CharField(max_length=100)
    date_of_birth = models.DateField(null=True, blank=True) # Date of birth might be unknown. 
    date_of_death = models.DateField('Died', null=True, blank=True)
    # NOTE: What does 'Died' mean? Does it specify the only choice?


    # https://docs.djangoproject.com/en/1.8/ref/urlresolvers/#reverse
    def get_absolute_url(self):
        """
        Returns the url to access a particular author instance. 
        """

        return reverse('author-detail', args=[str(self.id)])


    def __str__(self):
        """
        String for representing the Model object. 
        """

        return '%s, %s' % (self.last_name, self.first_name)
1a3e3d13198cebcda67670dbc1cb5abe7c5b4fe9
<mask token>


class Language(models.Model):
    <mask token>
    <mask token>
    <mask token>


class Book(models.Model):
    """
    Model representing a book (but not a specific copy of a book).
    """
    title = models.CharField(max_length=200)
    author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
    summary = models.TextField(max_length=1000, help_text=
        'Enter a brief description of the book')
    isbn = models.CharField('ISBN', max_length=13, help_text=
        '13 Character <a href="https://www.isbn-international.org/content/what-isbn">ISBN number</a>'
        )
    genre = models.ManyToManyField(Genre, help_text=
        'Select a genre for this book.')
    language = models.ForeignKey('Language', on_delete=models.SET_NULL,
        null=True)

    def __str__(self):
        """
        String for representing the Model object. 
        """
        return self.title

    def get_absolute_url(self):
        """
        Returns the url to access a particular book instance. 
        """
        return reverse('book-detail', args=[str(self.id)])

    def display_genre(self):
        """
        Creates a string for the Genre. This is required to display genre in Admin.
        """
        return ', '.join([genre.name for genre in self.genre.all()[:3]])
    display_genre.short_description = 'Genre'


<mask token>


class BookInstance(models.Model):
    """
    Model representing a specific copy of a book (i.e. that can be borrowed from the library). 
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text=
        'Unique ID for this particular book accross whole library.')
    book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True)
    imprint = models.CharField(max_length=200)
    due_back = models.DateField(null=True, blank=True)
    LOAN_STATUS = ('d', 'Maintenance'), ('o', 'On loan'), ('a', 'Available'), (
        'r', 'Reserved')
    status = models.CharField(max_length=1, choices=LOAN_STATUS, blank=True,
        default='d', help_text='Book Availability')
    borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True,
        blank=True)

    @property
    def is_overdue(self):
        if date.today() > self.due_back:
            return True
        return False


    class Meta:
        ordering = ['due_back']
        permissions = ('can_mark_returned', 'Set book as returned'), (
            'can_renew', 'Renew book on loan')

    def __str__(self):
        """
        String for representing the Model object. 
        """
        return '%s (%s)' % (self.id, self.book.title)


class Author(models.Model):
    """
    Model representing the author.
    """
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    date_of_birth = models.DateField(null=True, blank=True)
    date_of_death = models.DateField('Died', null=True, blank=True)

    def get_absolute_url(self):
        """
        Returns the url to access a particular author instance. 
        """
        return reverse('author-detail', args=[str(self.id)])

    def __str__(self):
        """
        String for representing the Model object. 
        """
        return '%s, %s' % (self.last_name, self.first_name)

<mask token>


class Language(models.Model):
    """
    Model representing the language a book is written in (e.g. English, German, Chinese). 
    """
    name = models.CharField(max_length=200, help_text=
        'Enter the language the book is written in.')

    def __str__(self):
        """
        String for representing the model object (in Admin site etc.)
        """
        return self.name


class Book(models.Model):
    """
    Model representing a book (but not a specific copy of a book).
    """
    title = models.CharField(max_length=200)
    author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
    summary = models.TextField(max_length=1000, help_text=
        'Enter a brief description of the book')
    isbn = models.CharField('ISBN', max_length=13, help_text=
        '13 Character <a href="https://www.isbn-international.org/content/what-isbn">ISBN number</a>'
        )
    genre = models.ManyToManyField(Genre, help_text=
        'Select a genre for this book.')
    language = models.ForeignKey('Language', on_delete=models.SET_NULL,
        null=True)

    def __str__(self):
        """
        String for representing the Model object. 
        """
        return self.title

    def get_absolute_url(self):
        """
        Returns the url to access a particular book instance. 
        """
        return reverse('book-detail', args=[str(self.id)])

    def display_genre(self):
        """
        Creates a string for the Genre. This is required to display genre in Admin.
        """
        return ', '.join([genre.name for genre in self.genre.all()[:3]])
    display_genre.short_description = 'Genre'


<mask token>


class BookInstance(models.Model):
    """
    Model representing a specific copy of a book (i.e. that can be borrowed from the library). 
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text=
        'Unique ID for this particular book accross whole library.')
    book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True)
    imprint = models.CharField(max_length=200)
    due_back = models.DateField(null=True, blank=True)
    LOAN_STATUS = ('d', 'Maintenance'), ('o', 'On loan'), ('a', 'Available'), (
        'r', 'Reserved')
    status = models.CharField(max_length=1, choices=LOAN_STATUS, blank=True,
        default='d', help_text='Book Availability')
    borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True,
        blank=True)

    @property
    def is_overdue(self):
        if date.today() > self.due_back:
            return True
        return False


    class Meta:
        ordering = ['due_back']
        permissions = ('can_mark_returned', 'Set book as returned'), (
            'can_renew', 'Renew book on loan')

    def __str__(self):
        """
        String for representing the Model object. 
        """
        return '%s (%s)' % (self.id, self.book.title)


class Author(models.Model):
    """
    Model representing the author.
    """
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    date_of_birth = models.DateField(null=True, blank=True)
    date_of_death = models.DateField('Died', null=True, blank=True)

    def get_absolute_url(self):
        """
        Returns the url to access a particular author instance. 
        """
        return reverse('author-detail', args=[str(self.id)])

    def __str__(self):
        """
        String for representing the Model object. 
        """
        return '%s, %s' % (self.last_name, self.first_name)

<mask token>


class Genre(models.Model):
    <mask token>
    name = models.CharField(max_length=200, help_text=
        'Enter a book genre (e.g. Science Fiction, French Poetry etc.)')

    def __str__(self):
        """
        String for representing the Model object (in Admin site etc.)
        """
        return self.name


class Language(models.Model):
    """
    Model representing the language a book is written in (e.g. English, German, Chinese). 
    """
    name = models.CharField(max_length=200, help_text=
        'Enter the language the book is written in.')

    def __str__(self):
        """
        String for representing the model object (in Admin site etc.)
        """
        return self.name


class Book(models.Model):
    """
    Model representing a book (but not a specific copy of a book).
    """
    title = models.CharField(max_length=200)
    author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
    summary = models.TextField(max_length=1000, help_text=
        'Enter a brief description of the book')
    isbn = models.CharField('ISBN', max_length=13, help_text=
        '13 Character <a href="https://www.isbn-international.org/content/what-isbn">ISBN number</a>'
        )
    genre = models.ManyToManyField(Genre, help_text=
        'Select a genre for this book.')
    language = models.ForeignKey('Language', on_delete=models.SET_NULL,
        null=True)

    def __str__(self):
        """
        String for representing the Model object. 
        """
        return self.title

    def get_absolute_url(self):
        """
        Returns the url to access a particular book instance. 
        """
        return reverse('book-detail', args=[str(self.id)])

    def display_genre(self):
        """
        Creates a string for the Genre. This is required to display genre in Admin.
        """
        return ', '.join([genre.name for genre in self.genre.all()[:3]])
    display_genre.short_description = 'Genre'


<mask token>


class BookInstance(models.Model):
    """
    Model representing a specific copy of a book (i.e. that can be borrowed from the library). 
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text=
        'Unique ID for this particular book accross whole library.')
    book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True)
    imprint = models.CharField(max_length=200)
    due_back = models.DateField(null=True, blank=True)
    LOAN_STATUS = ('d', 'Maintenance'), ('o', 'On loan'), ('a', 'Available'), (
        'r', 'Reserved')
    status = models.CharField(max_length=1, choices=LOAN_STATUS, blank=True,
        default='d', help_text='Book Availability')
    borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True,
        blank=True)

    @property
    def is_overdue(self):
        if date.today() > self.due_back:
            return True
        return False


    class Meta:
        ordering = ['due_back']
        permissions = ('can_mark_returned', 'Set book as returned'), (
            'can_renew', 'Renew book on loan')

    def __str__(self):
        """
        String for representing the Model object. 
        """
        return '%s (%s)' % (self.id, self.book.title)


class Author(models.Model):
    """
    Model representing the author.
    """
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    date_of_birth = models.DateField(null=True, blank=True)
    date_of_death = models.DateField('Died', null=True, blank=True)

    def get_absolute_url(self):
        """
        Returns the url to access a particular author instance. 
        """
        return reverse('author-detail', args=[str(self.id)])

    def __str__(self):
        """
        String for representing the Model object. 
        """
        return '%s, %s' % (self.last_name, self.first_name)

from django.db import models
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from datetime import date


class Genre(models.Model):
    """
    Model representing a book genre (e.g. Science Fiction, Non Fiction). 
    """
    name = models.CharField(max_length=200, help_text=
        'Enter a book genre (e.g. Science Fiction, French Poetry etc.)')

    def __str__(self):
        """
        String for representing the Model object (in Admin site etc.)
        """
        return self.name


class Language(models.Model):
    """
    Model representing the language a book is written in (e.g. English, German, Chinese). 
    """
    name = models.CharField(max_length=200, help_text=
        'Enter the language the book is written in.')

    def __str__(self):
        """
        String for representing the model object (in Admin site etc.)
        """
        return self.name


class Book(models.Model):
    """
    Model representing a book (but not a specific copy of a book).
    """
    title = models.CharField(max_length=200)
    author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
    summary = models.TextField(max_length=1000, help_text=
        'Enter a brief description of the book')
    isbn = models.CharField('ISBN', max_length=13, help_text=
        '13 Character <a href="https://www.isbn-international.org/content/what-isbn">ISBN number</a>'
        )
    genre = models.ManyToManyField(Genre, help_text=
        'Select a genre for this book.')
    language = models.ForeignKey('Language', on_delete=models.SET_NULL,
        null=True)

    def __str__(self):
        """
        String for representing the Model object. 
        """
        return self.title

    def get_absolute_url(self):
        """
        Returns the url to access a particular book instance. 
        """
        return reverse('book-detail', args=[str(self.id)])

    def display_genre(self):
        """
        Creates a string for the Genre. This is required to display genre in Admin.
        """
        return ', '.join([genre.name for genre in self.genre.all()[:3]])
    display_genre.short_description = 'Genre'


import uuid


class BookInstance(models.Model):
    """
    Model representing a specific copy of a book (i.e. that can be borrowed from the library). 
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text=
        'Unique ID for this particular book accross whole library.')
    book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True)
    imprint = models.CharField(max_length=200)
    due_back = models.DateField(null=True, blank=True)
    LOAN_STATUS = ('d', 'Maintenance'), ('o', 'On loan'), ('a', 'Available'), (
        'r', 'Reserved')
    status = models.CharField(max_length=1, choices=LOAN_STATUS, blank=True,
        default='d', help_text='Book Availability')
    borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True,
        blank=True)

    @property
    def is_overdue(self):
        if date.today() > self.due_back:
            return True
        return False


    class Meta:
        ordering = ['due_back']
        permissions = ('can_mark_returned', 'Set book as returned'), (
            'can_renew', 'Renew book on loan')

    def __str__(self):
        """
        String for representing the Model object. 
        """
        return '%s (%s)' % (self.id, self.book.title)


class Author(models.Model):
    """
    Model representing the author.
    """
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    date_of_birth = models.DateField(null=True, blank=True)
    date_of_death = models.DateField('Died', null=True, blank=True)

    def get_absolute_url(self):
        """
        Returns the url to access a particular author instance. 
        """
        return reverse('author-detail', args=[str(self.id)])

    def __str__(self):
        """
        String for representing the Model object. 
        """
        return '%s, %s' % (self.last_name, self.first_name)

from django.db import models
# Import the User model, so User is available to subsequent code that makes use of it.
from django.contrib.auth.models import User

# http://stackoverflow.com/questions/30471812/global-name-reverse-is-not-defined
from django.core.urlresolvers import reverse
from datetime import date # Used in 'is_overdue' function

# Create your models here.
class Genre(models.Model):
    """
    Model representing a book genre (e.g. Science Fiction, Non Fiction). 
    """

    name = models.CharField(max_length=200, help_text="Enter a book genre (e.g. Science Fiction, French Poetry etc.)")

    def __str__(self):
        """
        String for representing the Model object (in Admin site etc.)
        """

        return self.name


# =============================================================================

class Language(models.Model):
    """
    Model representing the language a book is written in (e.g. English, German, Chinese). 
    """
    # NOTE: A language can be associated to MANY books.

    name = models.CharField(max_length=200, help_text="Enter the language the book is written in.")

    def __str__(self):
        """
        String for representing the model object (in Admin site etc.)
        """

        return self.name




# =============================================================================

class Book(models.Model):
    """
    Model representing a book (but not a specific copy of a book).
    """

    title = models.CharField(max_length=200)
    author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
    # Foreign Key used because book can only have one author, but authors can have multiple books. 
    # NOTE: This is not true, somtimes a book is written by several authors. 
    #       => Should be ManyToManyField intead.
    # Author as a string (for now) rather than object because it hasn't been declared yet in the file.
    summary = models.TextField(max_length=1000, help_text="Enter a brief description of the book")
    isbn    = models.CharField('ISBN', max_length=13, help_text='13 Character <a href="https://www.isbn-international.org/content/what-isbn">ISBN number</a>')
    genre   = models.ManyToManyField(Genre, help_text="Select a genre for this book.")
    # ManyToManyField used because genre can contain many books. Books can cover many genres. 
    # Genre class has already been defined, so we can specify the object above. 

    # A book is associated with ONE and only ONE langage => ForeignKey
    language = models.ForeignKey('Language', on_delete=models.SET_NULL, null=True)

    def __str__(self):
        """
        String for representing the Model object. 
        """
        
        return self.title

    # https://docs.djangoproject.com/en/1.8/ref/urlresolvers/#reverse
    def get_absolute_url(self):
        """
        Returns the url to access a particular book instance. 
        """
        return reverse('book-detail', args=[str(self.id)])  
        # Returns an URL that can be used to access a detail record for this model 
        # (for this to work we will have to 
        # -- Define a URL mapping that has the name 'book-detail' (name='book-detail')
        # -- Define an associated view.
        # -- Define an associated template.


    def display_genre(self):
        """
        Creates a string for the Genre. This is required to display genre in Admin.
        """
         
        # Get first 3 genres and join to a string.
        return ', '.join([ genre.name for genre in self.genre.all()[:3] ])

    display_genre.short_description = 'Genre'



# =============================================================================

import uuid # Required for unique book instances.

class BookInstance(models.Model):
    """
    Model representing a specific copy of a book (i.e. that can be borrowed from the library). 
    """

    id = models.UUIDField(
        primary_key=True, 
        default=uuid.uuid4, 
        help_text="Unique ID for this particular book accross whole library.",
    )

    # ForeignKey (one-to many) 
    book = models.ForeignKey(
        'Book',
        on_delete=models.SET_NULL,
        null=True,
    )

    imprint = models.CharField(max_length=200)

    due_back = models.DateField(null=True, blank=True)
    # Set to Null when the book is available, because then there is no due date.

    LOAN_STATUS = (
        ('d', 'Maintenance'),
        ('o', 'On loan'),
        ('a', 'Available'),
        ('r', 'Reserved'),
    )

    status = models.CharField(
        max_length=1, 
        choices=LOAN_STATUS, 
        blank=True,  # If no value given, the default value is used.
        default='d', # Because a book will initially be created unavailable before being stocked on the shelve.
        help_text="Book Availability",
    )

    borrower = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
    )

    # Add a property that we can call from our templates
    # from datetime import date # Called at the top of the file
    @property
    def is_overdue(self):
        if date.today() > self.due_back:
            return True
        return False


    class Meta:
        ordering = ["due_back"]

        # Assign permission to "Librarian" group in the Admin site.
        permissions = (
            ("can_mark_returned", "Set book as returned"),
            ("can_renew",         "Renew book on loan"),
        )
        # Next Permission Steps:
        # =========================
        # NOTE 1: After running the migrations, the new permissions will be selectable 
        #         in the Admin for each group: http://127.0.0.1:8000/admin/auth/group/
        # NOTE 2: Templates: Check for permission with {{ perms.catalog.can_mark_returned }}
        # NOTE 3: Views
        # - Class-based: 
        # --------------------------
        #   from django.contrib.auth.mixins import PermissionRequiredMixin
        #   class MyView(PermissionRequiredMixin, View):
        #       permission_required = ('catalog.can_mark_returned', 'catalog.can_edit')
        # - Function-based:
        # --------------------------
        #   from django.contrib.auth.decorators import permission_required
        #   @permission_required('catalog.can_mark_returned')
        #   @permission_required('catalog.can_edit')
        #   def my_view(request):
        # NOTE: Testing for  a permission also tests for authentication.

    
    def __str__(self):
        """
        String for representing the Model object. 
        """

        return '%s (%s)' % (self.id, self.book.title)


# =============================================================================

class Author(models.Model):
    """
    Model representing the author.
    """

    first_name = models.CharField(max_length=100)
    last_name  = models.CharField(max_length=100)
    date_of_birth = models.DateField(null=True, blank=True) # Date of birth might be unknown. 
    date_of_death = models.DateField('Died', null=True, blank=True)
    # NOTE: What does 'Died' mean? Does it specify the only choice?


    # https://docs.djangoproject.com/en/1.8/ref/urlresolvers/#reverse
    def get_absolute_url(self):
        """
        Returns the url to access a particular author instance. 
        """

        return reverse('author-detail', args=[str(self.id)])


    def __str__(self):
        """
        String for representing the Model object. 
        """

        return '%s, %s' % (self.last_name, self.first_name)