Coverage for catalog/models.py: 91.78%
69 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-13 15:39 -0700
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-13 15:39 -0700
1import uuid
2from datetime import date
4from django.contrib.auth import get_user_model
5from django.db import models
6from django.urls import reverse
9class Genre(models.Model):
10 name = models.CharField(max_length=200, help_text="Enter a book genre")
12 class Meta:
13 ordering = ["name"]
15 def __str__(self):
16 return self.name 1m
19class Language(models.Model):
20 name = models.CharField(max_length=200, help_text="Enter the book's language")
22 class Meta:
23 ordering = ["name"]
25 def __str__(self):
26 return self.name 1n
29class Book(models.Model):
30 title = models.CharField(max_length=200)
31 author = models.ForeignKey("Author", on_delete=models.SET_NULL, null=True)
32 pages = models.IntegerField(null=True, blank=True, help_text="Number of Pages")
33 publisher = models.CharField(max_length=40, blank=True)
34 pubdate = models.DateField(null=True, blank=True, help_text="Date Published")
35 summary = models.TextField(
36 max_length=1000, help_text="Enter a brief description of the book."
37 )
38 isbn = models.CharField(
39 "ISBN",
40 max_length=13,
41 unique=True,
42 help_text="13 Character <a href='https://www.isbn-international.org/content/what-isbn'>ISBN number</a>",
43 )
44 genre = models.ManyToManyField(Genre, help_text="Select a genre for this book")
45 language = models.ForeignKey("Language", on_delete=models.SET_NULL, null=True)
46 cover = models.ImageField(upload_to="covers/", blank=True)
48 class Meta:
49 ordering = ["title", "author"]
51 def __str__(self):
52 return self.title 1o
54 def get_absolute_url(self):
55 return reverse("book-detail", args=[str(self.id)]) 1p
57 def display_genre(self):
58 """Creates a string for Genre. Required for Admin display"""
59 return ", ".join([genre.name for genre in self.genre.all()[:3]])
61 display_genre.short_description = "Genre"
64class BookInstance(models.Model):
65 """Represents a specific copy of a book"""
67 id = models.UUIDField(
68 primary_key=True,
69 default=uuid.uuid4,
70 help_text="Unique ID for this book across whole library",
71 )
72 book = models.ForeignKey("Book", on_delete=models.RESTRICT, null=True)
73 imprint = models.CharField(max_length=200)
74 due_back = models.DateField(null=True, blank=True)
75 borrower = models.ForeignKey(
76 get_user_model(), on_delete=models.SET_NULL, null=True, blank=True
77 )
79 LOAN_STATUS = (
80 ("m", "Maintenance"),
81 ("o", "On Loan"),
82 ("a", "Available"),
83 ("r", "Reserved"),
84 )
86 status = models.CharField(
87 max_length=1,
88 choices=LOAN_STATUS,
89 blank=True,
90 default="m",
91 help_text="Book Availability",
92 )
94 class Meta:
95 ordering = ["due_back"]
96 permissions = (("can_mark_returned", "Set book as returned"),)
98 def __str__(self):
99 return "{0} ({1})".format(self.id, self.book.title)
101 @property
102 def is_overdue(self):
103 if self.due_back and date.today() > self.due_back: 103 ↛ 104line 103 didn't jump to line 104 because the condition on line 103 was never true1defghijk
104 return True
105 return False 1defghijk
108class Author(models.Model):
109 first_name = models.CharField(max_length=100)
110 middle_name = models.CharField(
111 max_length=100, blank=True, help_text="Middle Name(initial)"
112 )
113 last_name = models.CharField(max_length=100)
114 date_of_birth = models.DateField(null=True, blank=True)
115 date_of_death = models.DateField("Died", null=True, blank=True)
117 class Meta:
118 ordering = ["last_name", "first_name"]
120 def __str__(self):
121 if self.middle_name is not None: 121 ↛ 124line 121 didn't jump to line 124 because the condition on line 121 was always true1albc
122 return f"{self.last_name}, {self.first_name} {self.middle_name}" 1albc
123 else:
124 return f"{self.last_name}, {self.first_name}"
126 def get_absolute_url(self):
127 return reverse("author-detail", args=[str(self.id)]) 1aqrbc