i create new Column and add customize render as below
class PriceColumn(django_tables2.Column):
def render(self, value):
if isinstance(value, int) or isinstance(value, float):
self.attrs['td']['title'] = f'{round(value, 2):,}'
return number_convertor_to_milion(value)
return '---
then i used it for field
weekly_returns = PriceColumn(verbose_name=_('Weekly Returns'))
def render_weekly_returns(self, value,**kwargs):
final_result = value*100
// i want to call super().render() like below
return super().render(final_result,**kwargs)
i want to call super as in code writed but gives error
AttributeError: 'super' object has no attribute 'render'
how can do this?
In your case super() is referring to the class it's in, which is the MyTable(tables.Table) class, not the intended PriceColumn(Column) class.
You can fix one of 2 ways, call to the Class method directly;
def render_weekly_returns(self, value,**kwargs):
final_result = value*100
return PriceColumn.render(final_result,**kwargs)
or I would probably recommend just adding the return method instructions into your render_weekly_returns() method as it's going to be easier to read in the future.
def render_weekly_returns(self, value,**kwargs):
final_result = value*100
if isinstance(final_result, int) or isinstance(final_result, float):
self.attrs['td']['title'] = f'{round(final_result, 2):,}'
return number_convertor_to_milion(final_result)
return '---'
Related
How do you set/get the values of attributes of t given by x?
class Test:
def __init__(self):
self.attr1 = 1
self.attr2 = 2
t = Test()
x = "attr1"
There are built-in functions called getattr and setattr
getattr(object, attrname)
setattr(object, attrname, value)
In this case
x = getattr(t, 'attr1')
setattr(t, 'attr1', 21)
If you want to keep the logic hidden inside the class, you may prefer to use a generalized getter method like so:
class Test:
def __init__(self):
self.attr1 = 1
self.attr2 = 2
def get(self,varname):
return getattr(self,varname)
t = Test()
x = "attr1"
print ("Attribute value of {0} is {1}".format(x, t.get(x)))
Outputs:
Attribute value of attr1 is 1
Another apporach that could hide it even better would be using the magic method __getattribute__, but I kept getting an endless loop which I was unable to resolve when trying to get retrieve the attribute value inside that method.
Also note that you can alternatively use vars(). In the above example, you could exchange getattr(self,varname) by return vars(self)[varname], but getattrmight be preferable according to the answer to What is the difference between vars and setattr?.
Note: This answer is very outdated. It applies to Python 2 using the new module that was deprecated in 2008.
There is python built in functions setattr and getattr. Which can used to set and get the attribute of an class.
A brief example:
>>> from new import classobj
>>> obj = classobj('Test', (object,), {'attr1': int, 'attr2': int}) # Just created a class
>>> setattr(obj, 'attr1', 10)
>>> setattr(obj, 'attr2', 20)
>>> getattr(obj, 'attr1')
10
>>> getattr(obj, 'attr2')
20
hi i couldn't solve this problem. I would appreciate if you help.
class Musabaka(models.Model):
kuno=models.ForeignKey(Club,on_delete=models.CASCADE,verbose_name="Kulüp")
seno=models.ForeignKey(Sezon,on_delete=models.CASCADE,verbose_name="Sezon")
rano=models.ForeignKey(takimlar,on_delete=models.CASCADE,verbose_name="Rakip Takım")
katno=models.ForeignKey(Kategori,on_delete=models.CASCADE,verbose_name="Kategori")
mtarih=models.DateTimeField(auto_now_add=False,verbose_name="Müsabaka Tarihi")
def __str__(self):
return self.rano
how should I try a method
class takimlar(models.Model):
kno=models.ForeignKey(Club,on_delete=models.CASCADE)
takim=models.CharField(max_length=50)
created_date=models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.takim)
The error is quite self-explaining. In your first model, you write:
def __str__(self):
return self.rano
But rano is a takimlar object, since you defined a ForeignKey to the takimlar model. You can take the textual representation of that object, by wrapping it in the str constructor:
class Musabaka(models.Model):
# ...
def __str__(self):
return str(self.rano)
As for the takimlar model, you do not need to call str(..) on that, since the takim is a CharField, hense self.takim is already a string, so:
class takimlar(models.Model):
# ...
def __str__(self):
return self.takim
May be I do not completely understand the concept of properties in python, but I am confused by the behaviour of my Python program.
I have a class like this:
class MyClass():
def __init__(self, value):
self._value = value
#property
def value(self):
return self._value
#value.setter
def value(self, value):
self._value = value
What I would expect is, that calling MyClass.value = ... changes the content of _value. But what actually happened is this:
my_class = MyClass(1)
assert my_class.value == 1 # true
assert my_class._value == 1 # true
my_class.value = 2
assert my_class.value == 2 # true
assert my_class._value == 2 # false! _value is still 1
Did I make a mistake while writing the properties or is this really the correct behaviour? I know that I should not call my_class._value for reading the value, but nevertheless I would expect that it should work, anyway. I am using Python 2.7.
The class should inherit object class (in other word, the class should be new-style class) to use value.setter. Otherwise setter method is not called.
class MyClass(object):
^^^^^^
I am trying to use google's ndb model, adding some auto fields and definitions prior to model definition. The below code works well. My question is, though, any specific ndb model implementation is not used ( given I will be destroyed, if google changes anything) do you see any issue with portability of below
class MetaModel(type):
def __new__(cls,name,bases,attrs):
super_new = super(MetaModel,cls).__new__
if name == "Model":
return super_new(cls,name,bases,attrs)
if attrs.get('auto_date_time',True):
attrs['date_add'] = ndb.DateTimeProperty(auto_now_add= True)
attrs['date_upd'] = ndb.DateTimeProperty(auto_now= True)
attrs['_get_kind'] = classmethod(get_kind)
attrs['__name__'] = name
attr_meta = attrs.get('Meta',None)
if attr_meta is None:
meta = type('meta',(object,),dict())
else:
meta = attr_meta
kwargs= {}
model_module = sys.modules[attrs['__module__']]
kwargs['app_label'] = model_module.__name__.split('.')[-2]
_meta = Options(meta,name,**kwargs)
attrs['_meta'] = _meta
return type(name,(ndb.Model,),attrs)
class Model(object):
__metaclass__ = MetaModel
class TesTModel(Model):
name = ndb.StringProperty(indexed=False)
tm = TestModel(name='This is the test model')
tm.put()
This seems pretty fragile. Sounds like an expando model might work for you?
Edit (based on clarification below): metaclasses and type really should be a last resort. They're confusing and hard to get right. For example, in your code snippet, subclasses of Model get ndb's metaclass instead of the one above:
class T1(Model):
pass
>>> T1().to_dict()
T1 {'date_upd': None, 'date_add': None}
class T2(Model):
auto_date_time = False
class T3(T2):
auto_date_time = True
>>> T2.__metaclass__
<class 'ndb.model.MetaModel'>
>>> T3().to_dict()
{}
You can avoid some craziness by deriving your metaclass from ndb.MetaModel:
class MyMetaModel(ndb.MetaModel):
def __new__(cls, name, bases, attrs):
return super(MyMetaModel,cls).__new__(cls, name, bases, attrs)
class MyModel(ndb.Model):
__metaclass__ = MyMetaModel
class AutoTimeModel(MyModel):
date_add = ndb.DateTimeProperty(auto_now_add=True)
date_upd = ndb.DateTimeProperty(auto_now=True)
I'm attempting to create a custom form field that works the same as float field for all intents and purposes, but that (by default) outputs the float value with no trailing zeros e.g. 33 rather than 33.0
I attempted to simply extend django.forms.FloatField like so:
class CustomFloatField(django.forms.FloatField):
def to_python(self, value):
"""
Returns the value without trailing zeros.
"""
value = super(django.forms.FloatField, self).to_python(value)
# code to strip trailing zeros
return stripped_value
But this ended up with me getting validation errors. When I looked closer at the FloatField class I noticed that in its own to_python() method it calls super(IntegerField, self).to_python(value) which checks to ensure the value can be cast to an int, and it was here that my code seemed to trip up. This has left me thoroughly confused. How does FloatField work at all if it has to try and cast it's value to an int? :)
Most likely I'm barking entirely up the wrong tree here but if someone could point me in the right direction I'd be grateful.
Your hunch is right - FloatField isn't really calling on the to_python method of IntegerField. To illustrate what's really going on,
class A(object):
def __init__(self):
print "A initialized"
def to_python(self, value):
print "A: to_python"
return value
class B(A):
def __init__(self):
print "B initialized"
def to_python(self, value):
value = super(B, self).to_python(value)
print "B: value = "
print int(value)
return int(value)
class C(B):
def to_python(self, value):
value = super(B, self).to_python(value)
print "C: value = "
print float(value)
return float(value)
c = C()
c.to_python(5.5)
gives the output,
B initialized
A: to_python
C: value =
5.5
To put it in context, the line in FloatField's to_python:
value = super(IntegerField, self).to_python(value)
is really calling up to Field's to_python, which is simply,
def to_python(self, value):
return value
before calling the rest of the code. This might help you further: Understanding Python super() with __init__() methods