0

Suppose we have a a Django model similar to this:

from mongoengine import (Document, StringField, DateTimeField)

class MyModel(Document):
    car = StringField()
    plane = StringField()
    name = StringField()
    some_field = SecretField()
    date = DateTimeField()
    # some more fields ...

Then, we want to take best matching object from our database for a given set of parameters, for example

@classmethod
def desired_method(cls, **kwargs):
    # for a given kwargs, choose the one that have fields in db
    # and return object for that parameter (ordered by date, say last one)

For example, calling MyModel.desired_method(car='Ford', name='Bettsy') would return last object created in db, with Ford car having name Bettsy.

On the other hand, calling MyModel.desired_method(plane='Airbus', some_field='hashed_msg', pilot='Ron', age='7') would return last object with specified plane and some_field fields, but others are ignored, as they do not exists in our model.

The purpose for all that is to be able to flexible extend functionality - let's say we are using model to add new objects to db, with specified car, name and some_field fields. With some populated db, we got request from client to start distinguish objects by another field version. We can't do it backwards, but we may add field version to our model, populate db with new entries, and change code in application from:

my_car = return_car()
my_name = return_name()
result = MyModel.desired_method(car=my_car, name=my_name)

to:

my_car = return_car()
my_name = return_name()
my_version = return_version()
result = MyModel.desired_method(car=my_car, name=my_name, version=my_version)

such that if we call MyModel.desired_method(car='Ford', name='Bettsy',version='123') we still get object for a given car and name, even if given entry does not have version (it was not in the model while adding to db - backward compatibility).

More generally, solution could be create a model with dynamically added fields - so for example

new_item = MyModel(name='John Doe', age='90')
new_item.save()

would create a new field age in the model, but I don't know if it is even possible

Photon Light
  • 757
  • 14
  • 26
  • What are you really trying to achieve? to have a generic model type, which could accomodate multiple kinds of objects?? – zaidfazil Jul 04 '17 at 09:08

1 Answers1

0
In [12]: class MyModel(Document):
    ...:     car = StringField()
    ...:     plane = StringField()
    ...:     name = StringField()
    ...:     some_field = StringField()
    ...:     date = DateTimeField()
    ...:     @queryset_manager
    ...:     def desired_method(cls, queryset, **kwargs):
    ...:         return queryset(**kwargs)
    ...:     

In [13]: MyModel.desired_method(car='Ford', name='Betsy')
Out[13]: []

In [14]: car = MyModel(car='Ford', name='Betsy').save()

In [15]: MyModel.desired_method(car='Ford', name='Betsy')
Out[15]: [<MyModel: MyModel object>]

does that answer your question?

Erdenezul
  • 597
  • 1
  • 7
  • 10