|
| 1 | +from django.db import models |
| 2 | + |
| 3 | +# Create your models here. |
| 4 | +from django.urls import reverse # Used to generate URLs by reversing the URL patterns |
| 5 | + |
| 6 | + |
| 7 | +class Genre(models.Model): |
| 8 | + """Model representing a book genre.""" |
| 9 | + name = models.CharField(max_length=200, help_text='Enter a book genre (e.g. Science Fiction)') |
| 10 | + |
| 11 | + def __str__(self): |
| 12 | + """String for representing the Model object.""" |
| 13 | + return self.name |
| 14 | + |
| 15 | + |
| 16 | +class Book(models.Model): |
| 17 | + """Model representing a book (but not a specific copy of a book).""" |
| 18 | + title = models.CharField(max_length=200) |
| 19 | + |
| 20 | + # Foreign Key used because book can only have one author, but authors can have multiple books |
| 21 | + # Author as a string rather than object because it hasn't been declared yet in the file |
| 22 | + author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True) |
| 23 | + |
| 24 | + summary = models.TextField(max_length=1000, help_text='Enter a brief description of the book') |
| 25 | + isbn = models.CharField('ISBN', max_length=13, unique=True, |
| 26 | + help_text='13 Character <a href="https://www.isbn-international.org/content/what-isbn">ISBN number</a>') |
| 27 | + |
| 28 | + # ManyToManyField used because genre can contain many books. Books can cover many genres. |
| 29 | + # Genre class has already been defined so we can specify the object above. |
| 30 | + genre = models.ManyToManyField(Genre, help_text='Select a genre for this book') |
| 31 | + |
| 32 | + def display_genre(self): |
| 33 | + """Create a string for the Genre. This is required to display genre in Admin.""" |
| 34 | + return ', '.join(genre.name for genre in self.genre.all()[:3]) |
| 35 | + |
| 36 | + display_genre.short_description = 'Genre' |
| 37 | + |
| 38 | + |
| 39 | + def __str__(self): |
| 40 | + """String for representing the Model object.""" |
| 41 | + return self.title |
| 42 | + |
| 43 | + def get_absolute_url(self): |
| 44 | + """Returns the url to access a detail record for this book.""" |
| 45 | + return reverse('book-detail', args=[str(self.id)]) |
| 46 | + |
| 47 | + |
| 48 | +import uuid # Required for unique book instances |
| 49 | + |
| 50 | + |
| 51 | +class BookInstance(models.Model): |
| 52 | + """Model representing a specific copy of a book (i.e. that can be borrowed from the library).""" |
| 53 | + id = models.UUIDField(primary_key=True, default=uuid.uuid4, |
| 54 | + help_text='Unique ID for this particular book across whole library') |
| 55 | + book = models.ForeignKey('Book', on_delete=models.RESTRICT, null=True) |
| 56 | + imprint = models.CharField(max_length=200) |
| 57 | + due_back = models.DateField(null=True, blank=True) |
| 58 | + |
| 59 | + LOAN_STATUS = ( |
| 60 | + ('m', 'Maintenance'), |
| 61 | + ('o', 'On loan'), |
| 62 | + ('a', 'Available'), |
| 63 | + ('r', 'Reserved'), |
| 64 | + ) |
| 65 | + |
| 66 | + status = models.CharField( |
| 67 | + max_length=1, |
| 68 | + choices=LOAN_STATUS, |
| 69 | + blank=True, |
| 70 | + default='m', |
| 71 | + help_text='Book availability', |
| 72 | + ) |
| 73 | + |
| 74 | + class Meta: |
| 75 | + ordering = ['due_back'] |
| 76 | + |
| 77 | + def __str__(self): |
| 78 | + """String for representing the Model object.""" |
| 79 | + return f'{self.id} ({self.book.title})' |
| 80 | + |
| 81 | + |
| 82 | +class Author(models.Model): |
| 83 | + """Model representing an author.""" |
| 84 | + first_name = models.CharField(max_length=100) |
| 85 | + last_name = models.CharField(max_length=100) |
| 86 | + date_of_birth = models.DateField(null=True, blank=True) |
| 87 | + date_of_death = models.DateField('Died', null=True, blank=True) |
| 88 | + |
| 89 | + class Meta: |
| 90 | + ordering = ['last_name', 'first_name'] |
| 91 | + |
| 92 | + def get_absolute_url(self): |
| 93 | + """Returns the url to access a particular author instance.""" |
| 94 | + return reverse('author-detail', args=[str(self.id)]) |
| 95 | + |
| 96 | + def __str__(self): |
| 97 | + """String for representing the Model object.""" |
| 98 | + return f'{self.last_name}, {self.first_name}' |
| 99 | + |
| 100 | + |
| 101 | +class MemberComment(models.Model): |
| 102 | + comment = models.TextField() |
| 103 | + timestamp = models.DateTimeField(auto_now_add=True) |
| 104 | + updated = models.DateTimeField(auto_now=True) |
0 commit comments