Where is the declaration of objects of django model? - python

In django documentation, it say that we can retrieve data entry as below
entry = Entry.objects.get(pk=1)
Entry is a model class in models.py. I tried to find the declaration of objects, but I can't find its declaration in manager.py, just know it is a instance of Manager. So, where is the declaration of objects? Does it represent a set of Entry instances?

When you define model, you extend Model class from django.db.models module.
It will provide default model manager in objects property.
If you want to define custom model manager, you can do it by subclassing django.db.models.Manager class.
Look at the docs how to do that: https://docs.djangoproject.com/en/1.11/topics/db/managers/
Add methods to custom model managers to if you want to manipulate with the collection of data. If you manipulate with single row, add method to your model.

It's defined in ModelBase, which is the metaclass for model classes. See https://github.com/django/django/blob/master/django/db/models/base.py#L360

Related

Create odoo model on view level

can we create a model in odoo so it could not reflect on database level?
For example:
class SalaOrder(model.models):
_name='sale.order'
I don't want to create "sale_order" table in database .
According to the comments on models.py (odoo/odoo/models.py) you can set _auto to False.
class SalaOrder(model.models):
_name = 'sale.order'
_auto = False
To comment says
_auto = False # don't create any database backend
Here are some more details about Odoo models (from the same code):
Odoo models are created by inheriting:
:class:Model for regular database-persisted models
:class:TransientModel for temporary data, stored in the database but
automatically vacuumed every so often
:class:AbstractModel for abstract super classes meant to be shared by
multiple inheriting models
The system automatically instantiates every model once per database. Those
instances represent the available models on each database, and depend on
which modules are installed on that database. The actual class of each
instance is built from the Python classes that create and inherit from the
corresponding model.
Every model instance is a "recordset", i.e., an ordered collection of
records of the model. Recordsets are returned by methods like
:meth:~.browse, :meth:~.search, or field accesses. Records have no
explicit representation: a record is represented as a recordset of one
record.
To create a class that should not be instantiated, the _register class
attribute may be set to False.

when should I write custom methods in model vs model manager/ queryset

when should I write methods in the model itself and when in the model manager?
is it like all methods to get something should be written in manager and others in model
There's a simple difference. Model methods act on a single instance. Manager methods create queries to act on multiple instances.

Access ORM models from different classes in Odoo/OpenERP

I am aware that you can get a reference to an existing model from within another model by using self.pool.get('my_model')
My question is, how can I get a reference to a model from a Python class that does NOT extend 'Model'?
In that case you will have to import the class like a normal Python class, writing in your .py file:
from your_path_class import YourClass
And then you will be able to work with it:
Yourclass.any_method()
By the way, self.pool.get('your model') in Odoo 8 API is self.env['your_model'].
It's pretty basic and simple any python class can be called from it's name space, so call your class from namespace and instanciate the class.
Even Model class or any class inherited from Model can be called and instanciated like this.
Self.pool is just orm cache to access framework persistent layer.
Bests

Django - get instances of base model as corresponding proxy models

I have a base Django model, and proxy models that subclass it. They override all methods. I need to iterate over all the instances of the base model (i.e. for i in BaseModel.objects.all()), but be able to call the methods of their corresponding proxy classes instead of the placeholder methods declared in the base class.
How do I approach this? I actually have a model field which can determine which proxy model corresponds to each particular instance. Maybe I can make use of it and cast the base class into the subclass somehow? I'm at a loss.
EDIT: I've had a look at this question and have managed to change the class by writing to self.__class__. However, is that safe to use with Django?
proxymodels = {"Foo": FooModel, "Bar": BarModel}
for o in BaseModel.objects.all():
proxymodels[o.type].method_name(o, *args, **kwargs)
The methods are called on the proxy models (the classes), passing the BaseModel instances as first argument plus any additional arguments you want to pass. That way the methods are called as if they were called on an instance of a proxy model.
PS: re-assigning self.__class__ seems very hackish to me.

Hook into django field assignment

When creating a "vanilla" python class, if one wants to execute code on assignment to an attribute, the usual pattern to to create a "protected" (leading-underscore) attribute to hold the data, and use property to create getters and setters.
Now, if I wanted to do that with a Django model, that would be unattractive, not least because I would have to search on the underscore-version of the property.
What is the recommended way to run code on field-assignment in Django?
There is no signal that I can find to do this; the only other approach I can see would be to use a custom Field that can register additional getter/setter handlers.
You simply can't do that on a non-custom field, because there is no actual "field": it's a simple attribute, with no class behind it.
You'll need to define a custom field class and override to_python - don't forget to set the metaclass to SubfieldBase.
It looks like dirtyfields is what you want. You can't intercept at exactly the same time the value is set, but you can hook in before saving. http://code.activestate.com/pypm/django-dirtyfields/
Alternatively, you should set up #properties with set methods. Of course this would require you to duplicate your actual django.db.models.fields fields with getters and setters.

Categories