Edgar Navasardyan
Edgar Navasardyan

Reputation: 4511

Writing generic functions for all types of Django models

What I need to achieve is best described by example. Imagine that I have multiple models (let's say, model Task and model Animals) that have a field named foo and my goal is to perform identical set of MySQL transactions for all of these models. For example, I want to increment by one all the foos of a given instance along with subsequent instances (with larger id's). Something like:

def example_view(instance):
    instance.foo = instance.foo + 1
    instance.save()
    id = instance.id
    INSTANCE_MODEL.objects.filter(id__gt = instance.id).update(foo = foo + 1)

The question is, is it possible in Django to write generic functions in a sense that I can use example_view with Animals, Tasks, etc, as long as all of them have fields mentioned in the view ? And if yes, what is the valid syntax for INSTANCE_MODEL.objects.... ?

Upvotes: 0

Views: 615

Answers (2)

Messaoud Zahi
Messaoud Zahi

Reputation: 1232

You can create a function in your models to increment by one all the foo like this:

class Task(models.Model):
    ....
    foo = ....

    def increment_foo(self):
        self.foo = self.foo + 1
        self.save()
        #increment by one all the foos
        Task.objects.filter(id__gt = self.id).update(foo = foo + 1)

class Animal(models.Model):
    ....
    foo = ....

    def increment_foo(self):
        self.foo = self.foo + 1
        self.save()
        #increment by one all the foos
        Animal.objects.filter(id__gt = self.id).update(foo = foo + 1)

you can call it in your view with: task_instance.increment_foo() or animal_instance.increment_foo()

Upvotes: 0

Marek Nowaczyk
Marek Nowaczyk

Reputation: 257

Try to use mixin.

def MixIn(pyClass, mixInClass):
    pyClass.__bases__ += (mixInClass,)

class Person(..sql model class..):
   ...
class Order(..sql model class..):


class MyMixinClass(object):
     def dummy(self):
        print("This method should be visible in Person and Order classes")

# apply mixin to Person and Order
MixIn(Person, MyMixinClass)
MixIn(Order, MyMixinClass)

p = Person()
p.dummy()  # it's ok

o = Order()
o.dummy()  # it's ok

Generally it would be nice to define another base class derived from ..sql model.. class.

class MyBaseModel(..sql model class..):
    def dummy(self):
       ...

class Person(MyBaseModel):
   ...

class Order(MyBaseModel):
   ....

You can give it a chance in Django, but in Pyramid and SQLAlchemy it doesn't work for some reason (that is unknown to me), so I use simply dynamic MixIn function.

Upvotes: 1

Related Questions