Reputation: 399
this not the first time to have the feeling stuck in a challenging new thing. but it may be the first to be not able to have an external blogs explaining the subject except the docs . so i hope to find some one explain the fundamentals of creating a custom django model field. here is an example if you want to know what i am facing
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:
# filter by objects with the same field values
# for the fields in "for_fields"
query = {field: getattr(model_instance, field)\
for field in self.for_fields}
qs = qs.filter(**query)
# get the order of the last item
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)
i have read some of the docs, but feel free to explain it as it's for any one with no prior experience so everyone will find it helpful
Upvotes: 0
Views: 177
Reputation: 399
class OrderField(PositiveIntegerField):
def __init__(self, for_fields=None, *args, **kwargs):
self.for_fields = for_fields
super().__init__(*args, **kwargs)
def pre_save(self, model_instance, add):
#if the field isn't existed yet in the object
#(as we could have saved the object before and resaving it for some reason like updating )
if getattr(model_instance, self.attname) is None: #self.attname is the name of the field in the model
try:
qs = self.model.objects.all()
if self.for_fields:
# get objects that has the same fields(with same vlaues) in for_fields
#it's like so
#for_fields = 'course, module, title'
# the query will be the value of these fields on the instance which we work on now(and have this field(orderfield ) and will be saved)
# course = 1 we assume it's one in this instanse
# module = 3 and so on for the title
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: 2
Reputation: 1991
From the look of it, it is inheriting the functionality of models.PositiveIntegerField
and modifying into a field with an ever increasing number - therefore the pre-save
that looks for the latest value and increments it by 1
Upvotes: 0