I'm trying to implement for methods for eac Model object in my project. get_all() , get_by_id(),add(),remove() and maybe others.
I need to use them by each object . When I declare an object automatically can call one of those methods.
The problem , I don't want to duplicate the code of the four methods in each class .
Is there a way to write them once, and link them to each object.
I heared about instance methods in python.
How can use this.
Please a help
Thanks
...
You can have a base manager which has all these methods and inherit them. Django model and manager inheritance
class MyModel(models.Model):
def get_all():
return <something>
class A(MyModel):
pass
class B(MyModel):
pass
You really should seperate row-level actions (like delete(), get_some_calculated_attribute()) which go in Model classes from table level actions (like create(), filter()) which go in Manager classes.
Related
What I am trying to do is best described by the following example:
class MyAbstractClass(models.Model):
abstract_field = IntegerField()
class Meta:
abstract = True
def abstract_method(self):
# THE ISSUE LIES IN THE LINE BELOW
ParentClass.objects.filter(..).update(....)
return self
class InheritedClass(MyAbstractClass):
# Field
def my_view(request):
obj = InheritedClass.objects.get(id=1)
obj.save()
return obj
So basically, the question is, is there any way in the abstract_method to tell Django to address the calling class (that is, InheritedClass)?
Technical answer : Well, quite simply yes :
def abstract_method(self):
type(self).objects.filter(..).update(....)
return self
Note that this is Python methods are called with the "calling" object (the object on which the method is invoked) as first parameter, and all attributes lookups will happens on this object and it's class - else inheritance just wouldn't work at all. The only django-specific part here is that Django prevents you from using a ModelManager on a model instance so you need to explicitely get the object's class, which is returned by type(self).
BUT :
Coding style considerations
Django recommands that model methods acting on the whole table should belong to the ModelManager (by contrast with methods acting on the current row only which are to be implemented as plain methods), so since your method obviously acts on the whole table it might be better as a ModelManager method.
I say "might" because there's a grey area, where updating one row implies updating some other rows too - a typical example is when you have a flag that should always only be set for one single record so you also want to unset it on all other records. There's (of course) not enough context in your question to tell which is the right choice here.
you can just do self.objects.filter(...).update(..)
An abstract class just implements methods that are inherited by its concrete class, here InheritedClass. Therefore, everything for methods and fields are available in the inheriting class.
However, for this instance, I would suggest you look at making a custom model manager. Methods in a model are meant to work with that specific row's fields, whereas managers are intended to work table-wide as described at model methods
Define custom methods on a model to add custom “row-level” functionality to your objects. Whereas Manager methods are intended to do “table-wide” things, model methods should act on a particular model instance.
If you have a method doing filtering in a model method, that is a code smell and it belongs in a custom Manager.
I'm using odooV10.
I want to know every model's methods without searching it manually, but I couldn't find anywhere to achieve this. Is anyone have any idea?
well you can simply dir(model)
ie.
any_method_on_your_model(self):
print dir(self)
you will see all the properties included in the object.
Activate the Developer Mode in OdooV10.
Then go Setting(odoo Main Settings)--> Technical -->Models.
Here you can find all models, fields, views and constraints. I hope this will work for you.
if not explain what you want trying to do.?
In python you can get method of class
get methods of class
but the problem here odoo inherits mechanism prevent you from doing
this. when you call a method a very complicated operation to create
an object with that method from the inherited classes
I am using Multi-Table inheritance (aka Concrete Inheritance), where I have a non-abstract model + DB Table called Clients, which is concerned with common details concerning all the clients.
But a client can be an Individual, Partnership or Company, for which I have created inheriting models and tables. An Individual has first name + last name, and company has other specific particulars, etc.
I want to be able to access the names of clients (derived from the columns from the child tables) when I want a list of all clients.
After lot of searching, I found that this tutorial, works successfully.
Basically, it involves inserting a column on the Client table, which will store the name of the Child model. Then using that name, the appropriate child model is identified and appropriate child method is accessed.
But it seems to be a slightly cumbersome way to implement polymorphism in Multi-Table inheritance.
I want to know whether since 2012, Django has introduced any better way to deal with the issue, or is this still the only way?
Please let me know if my code sample is required, but the link provided has a beautiful example already.
There is django-model-utils application with Inheritance Manager. It will cast automatically your parent class to children instances. Example from docs:
from model_utils.managers import InheritanceManager
class Place(models.Model):
# ...
objects = InheritanceManager()
class Restaurant(Place):
# ...
class Bar(Place):
# ...
nearby_places = Place.objects.filter(location='here').select_subclasses()
for place in nearby_places:
# "place" will automatically be an instance of Place, Restaurant, or Bar
Also check this question for generic solution with ContentType.
And also check awesome article by Jeff Elmore about this topic. Quite old, but still great.
I see in the Django documentation :
Model Instance reference : Creating objects
You may be tempted to customize the model by overriding the __init__ method. If you do so, however, take care not to change the calling signature as any change may prevent the model instance from being saved.
Rather than overriding __init__, try using one of these approaches:
Add a classmethod on the model class.
Add a method on a custom manager (usually preferred)
Why is the second solution "usually preferred" ?
In a situation where I have a model B which extends a model A through a OneToOne relation, and I want to create a method generating a B object which generates the corresponding A object as well, how is it "better" to use a custom manager as suggested, given I'll probably not use this manager for anything other than what is provided by default manager ?
I think it is preferred because it looks cleaner in code. You might also be reading into the emphasizes a bit too much, as the benefit or difference isn't that big. That said, when implementing things myself I do use the proposed approach.
Consider the following model (purely for illustrative purposes):
class Vehicle(models.Model):
wheels = models.IntegerField()
color = models.CharField(max_length=100)
In your application, the need often arises to get all cars, or all motorcycles, or whatever type of vehicle. To keep things DRY, you want some standard form of retrieving this data. By using class methods, you'd get the following:
class Vehicle(models.Model):
#(...)
#classmethod
def cars(cls):
return Vehicle.objects.filter(wheels=4)
cars = Vehicle.cars()
green_cars = Vehicle.cars().filter(color='green')
If you create a manager, you'll get something like this:
class CarManager(models.Manager):
def get_query_set(self):
return super(CarManager, self).get_query_set().filter(wheels=4)
class Vehicle(models.Model):
#(...)
car_objects = CarManager()
cars = Vehicle.car_objects.all()
green_cars = Vehicle.car_objects.filter(color='green')
In my opinion, the latter looks cleaner, especially when things get more complex. It keeps the clutter out of your model definitions, and keeps things similar to using the default objects manager.
I'm looking to do the opposite of what Django's proxy model does. I want to subclass Model, add some extra methods to it, add behavior to save(), set a default manager that adds some my-application-specific methods, and then subclass that to create most of the models in my application. Is this possible?
This just sounds like a simple case of model inheritance with an abstract base class.