user3256451
user3256451

Reputation: 475

How to create custom model fields in django, and how does it works

I am new to django development , I knew and always used defaults model fields provided by django, but while reading a book I came across the code which is given below and came to knew django has custom model field, can somebody let me know what below code does. Thanks for your response.

Models.py

class Module(models.Model):
  course = models.ForeignKey(Course, related_name='modules')
  title = models.CharField(max_length=200)
  description = models.TextField(blank=True)
  order = OrderField(blank=True, for_fields=['course'])

fields.py

class OrderField(models.PositiveIntegerField):
    def __init__(self, for_fields=None, *args, **kwargs):
        self.for_fields = for_fields
        super(OrderField, self).__init__(*args, **kwargs)

    def pre_save(self, model_instance, add):
        if getattr(model_instance, self.attname) is None:
            # no current value
            try:
                qs = self.model.objects.all()
                if self.for_fields:
                    query = {field: getattr(model_instance, field) for field in self.for_fields}

                    qs = qs.filter(**query)
                last_item = qs.latest(self.attname)
                value = last_item.order + 1

            except ObjectDoesNotExist:
                value = 0
            setattr(model_instance, self.attname, value)
            return value

        else:
            return super(OrderField,self).pre_save(model_instance, add)

Upvotes: 3

Views: 2466

Answers (1)

trixn
trixn

Reputation: 16354

This field keeps track of other entities that have the same value on the fields specified by the for_fields parameter. When you save a new instance of the model that has this field, it looks for other entities in the database with the same values on the in for_fields defined fields and store the amount of these plus one in the order field.

I guess that if you had e.g. a table of entities which you want to show to your user, you could sort the entities with same values on these fields by their order of creation/update depending on the order value.

Example:

Let's assume your have three Courses already in your database with the ids [1, 2, 3]

Now you create new Modules referencing one of these Courses.

Module(course_id=1, title='First').save() # No 1
Module(course_id=2, title='Second').save() # No 2
Module(course_id=1, title='Third').save() # No 3
Module(course_id=1, title='Fourth').save() # No 4

Your 4 new modules would now have the following value in the order field:

No 1: 0 (no other Module with course 1)

No 2: 0 (no other Module with course 2)

No 3: 1 (one other Module with course 1)

No 4: 2 (two other Modules already have course 1 referenced)

Now you could sort entities with the same course by the value of the order field putting them into the order of their creation.

Upvotes: 2

Related Questions