I'm having a strange issue
I have the implementation below:
In a controller
Event.search(search_params)
class Event < ApplicationRecord
def self.search(params)
find_events(params)
end
private
def find_events(params)
events = Event.upcoming
events = events.where("name like ?", "%#{params['name']}%")
events
end
end
When executed I get this error:
NoMethodError (undefined method `find_events' for #<Class:0x007fadcd00a690>)
What is wrong with my code?
You have to declare the class method with
def self.find_events
You cannot call an instance method from a class method without an instance object attached to that method.
Related
I got a Customer model which is related to a Company model. I'd like to give my factory the possibility to use a given company (if I need several customer from the same company). I thought to use the inner class Params to achieve that, but I got an issue using LazyAttribute and SubFactory together. Here is my factory:
class CustomerFactory(UserFactory):
"""
To be valid, customer needs to belong to one of these groups:
- manager
- regular
This can be achieved using the `set_group` parameter.
Example:
manager = CustomerFactory(set_group=manager_group)
"""
#lazy_attribute
def _company(self):
if self.use_company:
return self.use_company
else:
return SubFactory('rdt.tests.factories.CompanyFactory')
class Meta:
model = Customer
class Params:
use_company = None
#post_generation
def set_group(self, create, extracted, **kwargs):
if extracted:
self.groups.add(extracted)
I thought to use the factory as:
c1 = factories.CustomerFactory(use_company=my_company)
c2 = factories.CustomerFactory()
I got ValueError. It seems I can't get the parameter value 'use_company' in the factory.
Anyway my factory throws a ValueError.
I found a solution simply using an other post_generation method like this:
#post_generation
def set_group(self, create, extracted, **kwargs):
if extracted:
self.groups.add(extracted)
#post_generation
def company(self, create, extracted, **kwargs):
if extracted:
self._company = extracted
self.save()
I am using django 2.0.8 and Python 3.5. I have written a base class which encapsulates behavior in a base class.
When using the interface in the child class, I find that I have to pass the object of the child class to the parent - which is not only ugly, is error prone.
I do not want to use composition (instead of an interface), because AFAIK fields in django models are saved to the DB - that aside, I prefer the sub classing approach, since all the functionality can remain in the base class.
Is there any way I can (in the parent class), find/obtain the instance (or at least the name of the class and it's id) that invoked the method call?
Here is my code:
class Likeable(models.Model):
likes = GenericRelation(Like)
def action_is_permissible(self, actionable_object, actor):
ct = ContentType.objects.get_for_model(actionable_object)
object_id = actionable_object.id
found_objects = Like.objects.filter(content_type=ct, object_id=object_id, liker=actor)
return ((len(found_objects) == 0), ct, object_id, found_objects)
def add_like(self, actionable_object, actor):
can_add, ct, object_id, found_objects = self.action_is_permissible(actionable_object, actor)
if can_add:
like = self.likes.create(content_type=ct, object_id=object_id, liker=actor)
else:
# do nothing
return
class Meta:
abstract = True
class Foo(Likeable):
name = models.CharField(max_length=255,default='')
objects = models.Manager()
Example use (imports omitted)
foo = Foo.objects.get(id=1)
p = User.objects.get(id=1)
foo.add_like(foo, p) # <- nasty API calling convention
You can access it using self.
self refers to the object which is calling.
Ref: What is the purpose of self?
EDIT (code changes):
class Likeable(models.Model):
def add_like(self, actor):
# update `actionable_object` to `self`
foo.add_like(p)
Is it possible to define abstract static methods?
I'm trying:
abstract struct MyStruct
abstract def self.myfun # ERR
abstract def MyStruct::myfun # ERR
end
I faced the same problem and figured out a (in my opinion) nicer solution:
abstract class Something
module ClassMethods
abstract def some_abstract_class_method
end
extend ClassMethods
abstract def some_abstract_instance_method
end
The documentation mentions that module methods can be made abstract as well, so this builds on top of that.
Implementing this class without implementing the class method some_abstract_class_method will raise an error, as expected.
Abstract class methods don't appear to be a language feature:
abstract class Abstract
abstract self.doit
end
# => Syntax error in /home/bmiller/test.cr:23: unexpected token: self
However you could always delegate to an instance:
abstract class Parent
def self.instance
##instance ||= new
end
def self.doit
instance.doit
end
abstract def doit
end
class Child < Parent
def doit
"ok"
end
end
p Parent.doit # => can't instantiate abstract class Parent
p Child.doit # => "ok"
I have the following django models
class Charge(models.Model):
total = models.PositiveIntegerField()
def execute():
# make some external calls
return invoice_url
class Transaction(models.Model):
product = models.ForeignKey(Product)
charge = models.ForeignKey(Charge)
def do_charge():
self.charge = Charge.objects.create(total=self.product.price)
url = self.charge.execute()
return url
I'm trying to test do_charge by mocking the call to execute.
The problem is that the object is being created within do_charge.
Something like that (this is obviously not working just to illustrate)
#mock.patch('Charge.execute')
def test_should_return_url(self, mock):
mock.side_effect = 'www.foo.testing/invoice'
t = Transaction.objects.create(product=p1)
invoice_url = t.do_charge()
self.assertIsEqual(invoice_url, 'www.foo.testing/invoice')
Is it possible to mock Charge.execute?
python 3.4, django 1.8.
I've tried next code to test mock behavior and it seems that mocking Charge.execute should work.
>>> class A(object):
... def foo(self):
... return 'a'
>>> #mock.patch('__main__.A.foo', return_value='12')
... def bar(mockfoo):
... a = A()
... return a.foo()
...
>>> bar()
'12'
Here I've mocked a method of the class, make a class instance and called object's method and it used mocked version. So I think in your test mocked Charge.execute will be used. I think the problem you are facing can be related with correct path to the class you want to mock.
how could i get the AbstractClass of a Model in Django?
I tried to do it with type but type gives me the BaseModel class of django or the type of the model itself.
def go_for_the_bases(model):
while hasattr(model, '_meta'):
model = model.__base__
if hasattr(model, '_meta') and model._meta.abstract == True:
yield model
You can user mro() which stands for Method Resolution Order.
ClassName.mro()
which gives the tuple of the class, its base, its base's base, ...., and so on till we reach object.
You can loop over it and check for className._meta.abstract is True till you reach the abstract class.