Django/Django Model Field Tricks.md
... ...
@@ -0,0 +1,183 @@
1
+# 10 Django Model Field Tricks You Probably Didn’t Know About | by Haider Alaamery | Dec, 2024 | Medium
2
+
3
+https://halaamery.medium.com/10-django-model-field-tricks-you-probably-didnt-know-about-fc97f3148bc0
4
+
5
+![Haider Alaamery](https://miro.medium.com/v2/resize:fill:88:88/1*JF-tc5tO_oML1KH7Q5_oAQ.jpeg)
6
+[Haider Alaamery](https://halaamery.medium.com/)
7
+
8
+1\. Customizing Field Validation with `clean()`
9
+-----------------------------------------------
10
+
11
+Did you know you can add custom validation logic to specific fields using the `clean()` method?
12
+
13
+```
14
+from django.db import models
15
+from django.core.exceptions import ValidationError
16
+class Product(models.Model):
17
+ name = models.CharField(max_length=100)
18
+ price = models.DecimalField(max_digits=10, decimal_places=2)
19
+def clean(self):
20
+ if self.price <= 0:
21
+ raise ValidationError("Price must be greater than zero.")
22
+```
23
+
24
+
25
+> Use `clean()` in your save logic or forms to ensure that invalid data never sneaks into your database.
26
+
27
+2\. Conditional Default Values
28
+------------------------------
29
+
30
+Sometimes, you need default values to change dynamically based on some condition.
31
+
32
+```
33
+from django.utils.timezone import now
34
+class Event(models.Model):
35
+ name = models.CharField(max_length=100)
36
+ start_date = models.DateTimeField(default=now)
37
+ end_date = models.DateTimeField(default=lambda: now() + timedelta(days=7))
38
+```
39
+
40
+
41
+> This is great for timestamps or automatically generating default future dates.
42
+
43
+3\. **Unique Constraints for Multi-Field Uniqueness**
44
+-----------------------------------------------------
45
+
46
+Replace the deprecated unique\_together with UniqueConstraint for better control.
47
+
48
+```
49
+from django.db import models
50
+class Membership(models.Model):
51
+ user = models.ForeignKey('auth.User', on_delete=models.CASCADE)
52
+ group = models.ForeignKey('Group', on_delete=models.CASCADE)
53
+ class Meta:
54
+ constraints = [
55
+ models.UniqueConstraint(fields=['user', 'group'], name='unique_membership')
56
+ ]
57
+```
58
+
59
+
60
+> This ensures no user can be added to the same group twice.
61
+
62
+4\. **Using** `**choices**` **with Enums**
63
+------------------------------------------
64
+
65
+Django’s `choices` make fields cleaner, especially with Enums.
66
+
67
+```
68
+from django.db import models
69
+class Status(models.TextChoices):
70
+ PENDING = 'P', 'Pending'
71
+ APPROVED = 'A', 'Approved'
72
+ REJECTED = 'R', 'Rejected'
73
+class Request(models.Model):
74
+ status = models.CharField(max_length=1, choices=Status.choices, default=Status.PENDING)
75
+```
76
+
77
+
78
+> Access your choices like `Status.PENDING` instead of raw strings.
79
+
80
+5\. `through` for Many-to-Many Customization
81
+--------------------------------------------
82
+
83
+Need extra data in your Many-to-Many relationships? Use `through`.
84
+
85
+```
86
+class Author(models.Model):
87
+ name = models.CharField(max_length=100)
88
+class Book(models.Model):
89
+ title = models.CharField(max_length=100)
90
+ authors = models.ManyToManyField(Author, through='Authorship')
91
+class Authorship(models.Model):
92
+ author = models.ForeignKey(Author, on_delete=models.CASCADE)
93
+ book = models.ForeignKey(Book, on_delete=models.CASCADE)
94
+ role = models.CharField(max_length=50) # e.g., "Co-Author", "Editor"
95
+```
96
+
97
+
98
+> This allows you to track additional details about the relationship.
99
+
100
+6\. Field-Level Permissions with `editable=False`
101
+-------------------------------------------------
102
+
103
+Prevent direct editing in admin while still allowing updates programmatically.
104
+
105
+```
106
+class Order(models.Model):
107
+ total_price = models.DecimalField(max_digits=10, decimal_places=2, editable=False)
108
+```
109
+
110
+
111
+> You can still update `total_price` in your code but not in the admin.
112
+
113
+7\. Custom File Upload Paths
114
+----------------------------
115
+
116
+Organize uploaded files dynamically with `upload_to`.
117
+
118
+```
119
+def upload_to(instance, filename):
120
+ return f"uploads/{instance.user.id}/{filename}"
121
+class Profile(models.Model):
122
+ user = models.OneToOneField('auth.User', on_delete=models.CASCADE)
123
+ avatar = models.ImageField(upload_to=upload_to)
124
+```
125
+
126
+
127
+> Uploaded files are neatly stored based on the user’s ID.
128
+
129
+8\. Using `Property` Fields in Models
130
+-------------------------------------
131
+
132
+Django models can include computed properties.
133
+
134
+```
135
+class Employee(models.Model):
136
+ first_name = models.CharField(max_length=50)
137
+ last_name = models.CharField(max_length=50)
138
+ @property
139
+ def full_name(self):
140
+ return f"{self.first_name} {self.last_name}"
141
+```
142
+
143
+
144
+> Access it like a field: `employee.full_name`.
145
+
146
+9\. Auto-Setting Fields with `save()`
147
+-------------------------------------
148
+
149
+Customize field behavior by overriding `save()`.
150
+
151
+```
152
+class Article(models.Model):
153
+ title = models.CharField(max_length=100)
154
+ slug = models.SlugField(unique=True, blank=True)
155
+ def save(self, *args, **kwargs):
156
+ if not self.slug:
157
+ self.slug = self.title.lower().replace(' ', '-')
158
+ super().save(*args, **kwargs)
159
+```
160
+
161
+
162
+> Automatically generate slugs from titles if not provided.
163
+
164
+10\. Soft Deletes with `is_archived`
165
+------------------------------------
166
+
167
+Instead of deleting records, archive them.
168
+
169
+```
170
+class BaseModel(models.Model):
171
+ is_archived = models.BooleanField(default=False)
172
+ def delete(self, *args, **kwargs):
173
+ self.is_archived = True
174
+ self.save()
175
+ class Meta:
176
+ abstract = True
177
+```
178
+
179
+
180
+> Your data stays safe while appearing “deleted” to the user.
181
+
182
+**Conclusion:**
183
+Django’s model system is powerful, and these tricks can help you write cleaner, more efficient code. Which of these tricks are you already using? What’s your favorite?
... ...
\ No newline at end of file