10 Django Model Field Tricks You Probably Didn\342\200\231t Know About.md
... ...
@@ -1,183 +0,0 @@
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