overwrite save django method - python-3.x

I need to override Django's method save so when the purchase is made by a certain cpf, it is saved with "Approved" status. Can someone help me?
Follow the models.py
class Purchases(TimeStampedModel):
APROVADO = "AP"
EM_VALIDACAO = "VA"
STATUS_CHOICHES = (
(APROVADO, "Aprovado"),
(EM_VALIDACAO, "Em validação"),
)
values = models.DecimalField(decimal_places=2, max_digits=10, default=0)
cpf = BRCPFField("CPF")
status = models.CharField(max_length=20, choices=STATUS_CHOICHES, default=EM_VALIDACAO)

You just need to add a new method
def save(self, *args, **kwargs):
#your business logic
super().save(*args, **kwargs)

def save(self, *args, **kwargs):
if self.cpf == "15350946056":
self.status = "AP"
super(Purchases, self).save(*args, **kwargs)
else:
self.status = "VA"
super(Purchases, self).save(*args, **kwargs)
The CPF is between " " because the BRCPFField deals with charfild, we need to transform the cpf into a string so that there is a comparison

Related

How could I create a docstring decorator in the presence of properties?

I have a collection of ever more specialized classes which correspond to collections of the same kind of data (temperature, density, etc) but for different drifts, for example, one subclass has dimensions (nx, ny) and a different suclass has dimensions (ncv), and I want to reflect that in the docstrings, for having a better documentation using Sphinx.
After reading many very useful threads here in Stack Overflow, I have arrived to this model:
import numpy as np
from functools import wraps
def class_decorator(cls):
import ipdb; ipdb.set_trace()
clsdict = {}
mro = cls.mro()
mro.reverse()
for tmp in mro[1:]: ##Ignore object class parent.
clsdict.update(tmp.__dict__)
for name, method in clsdict.items():
if hasattr(method, '__og_doc__'):
try:
method.__doc__ = method.__og_doc__.format(**clsdict)
except:
pass
else:
try:
method.__og_doc__ = method.__doc__
method.__doc__ = method.__doc__.format(**clsdict)
except:
pass
return cls
def mark_documentation(fn):
if not hasattr(fn, '__og_doc__'):
try:
fn.__og_doc__ = fn.__doc__
except:
pass
#wraps(fn)
def wrapped(*args, **kwargs):
return fn(*args, **kwargs)
return wrapped
def documented_property(fn):
if not hasattr(fn, '__og_doc__'):
try:
fn.__og_doc__ = fn.__doc__
except:
pass
#wraps(fn)
def wrapped(*args, **kwargs):
return fn(*args, **kwargs)
prp= property(wrapped)
prp.__og_doc__ = fn.__og_doc__
return prp
#class_decorator
class Base(object):
_GRID_DIM = 'nx, ny'
_TYPE = 'BaseData'
def __init__(self, name):
self.name = name
def shape(self):
""" This docstring contains the type '{_TYPE}' of class."""
print('Simple')
def operation(self, a, b, oper=np.sum, **kwargs):
""" Test for functions with args and kwargs in {_TYPE}"""
return oper([a,b])
#classmethod
def help(cls, var):
try:
print(get(cls, var).__doc__)
except:
print("No docstring yet.")
#class_decorator
class Advanced(Base):
_GRID_DIM = 'ncv'
_TYPE = 'AdvancedData'
def __init__(self,name):
super().__init__(name)
#property
#mark_documentation
# #documented_property
def arkansas(self):
"""({_GRID_DIM}, ns): Size of Arkansaw."""
return 'Yeah'
I am aiming to get the correctly formatted docstring when I call the help method or I use Sphinx, so that:
> adv = Advanced('ADV')
> adv.help("arkansas")
(ncv, ns): Size of Arkansaw.
> adv.help("operation")
Test for functions with args and kwargs in AdvancedData
I have managed to make it work so far, except for properties, because I assigned __og_doc__ to the function, but the property does not have that attribute. My last attempt at monkeypatching this, documented_property, fails because property is inmutable (as expected), and I cannot come up with any way to avoid this roadblock.
Is there any way around this problem?

request.data.get getting None in patch method

I am trying to get the id of user but request.get.data is not getting when i tried to print staff_user its showing None.but when use json.loads its working fine but reguest.data.get is showing None.
class MyDetailsAPIView(RetrieveUpdateDestroyAPIView):
permission_classes = [IsAuthenticated]
parser_classes = [MyMultiPartParser]
serializer_class = Myserializer
model = Document
lookup_url_kwarg = 'file_id'
def patch(self, request, *args, **kwargs):
staff_user_pk = request.data.get('staff_user_pk')
if staff_user_pk:
try:
staffuser = Staffuser.objects.get(id=staff_user_pk)
except Staffuser.DoesNotExist as exc:
raise ValidationError({'detail': exc})
file = self.get_object()
file.staffusers.add(staffuser)
return super().patch(request, *args, **kwargs)

django __init__() takes 1 positional argument but 6 were given

My model class:
class Campaign(models.Model):
name = models.CharField(max_length=255)
campaign_id = models.CharField(max_length=8, null=False, blank=False, unique=True)
def __init__(self):
super(Campaign, self).__init__(self)
self.campaign_id = generate_random_id(8) # it generates just random string
class Meta:
ordering = ["name"]
def __str__(self):
return self.name
My view class:
def campaign_list(request):
campaigns = Campaign.objects.order_by('name').all()
return render(request, 'mp/campaign/list.html', {'campaigns': campaigns})
I got error
init() takes 1 positional argument but 6 were given
Before creating init in my model everything were working fine. But i assume that now Campaing.object.all() is using constructor and not str. How can i omit this and in .all still use just referring to name, not creating an object again?
why this is happening
I was getting the Below Error:
Response.__init__() take one positional argument but 2 were given
consider the example below having a function in views.py and returning the Response
but when I used the auto import extension in visual studio
Accidently I Imported the Response class from the requests module instead of rest_framework
# example
from requests import Response
#from rest_framework.response import Response
def hello_world_view(request):
return Response('ok')
Response class from request module
having 1 position argument
Response class from rest_framework
can have many position argument
It may work to pass *args, **kwargs as arguments in the init.
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) # dont have to pass self
self.campaign_id = generate_random_id(8) # it generates just random string
You can also override the save method
def save(self, *args, **kwargs):
self.campaign_id = generate_random_id(8)
super().save(*args, **kwargs)
Override save method instead of the initializer:
class Campaign(models.Model):
name = models.CharField(max_length=255)
campaign_id = models.CharField(max_length=8, unique=True)
def save(self, *args, **kwargs):
self.campaign_id = generate_random_id(8)
super().save(*args, **kwargs)
class Meta:
ordering = ["name"]
def __str__(self):
return self.name

Why doesn't __get__ method of metaclass get called?

I got class Op:
class Pipeable(type):
def __get__(self, instance, owner):
def pipe_within(*args, **kwargs):
return self(*args, op=instance, **kwargs)
print('piping...')
return pipe_within
class Op(metaclass=Pipeable):
def __init__(self, op=None):
if op is not None:
print('piped!')
self.op = op
self.__dict__[type(self).__name__] = type(self)
I expect Op class itself to work as descriptor, because its metaclass has __get__ method, but the code
op = Op().Op()
doesn't invoke Op.__get__. Why?
It is hard to tell what you really want there. But a metaclass that would add a property to itself at every new class maybe works better for whatever you want.
As far as I can understand your code, older classes won't be populated with references to the newer ones, as you create new instances (that in turn, get the reference for others).
On a second though, dinamically creating properties inisde __new__ seems hacky - but you can just implement the metaclass __getattr__ and __dir__ methods for much less convoluted code:
The simple version works for classes, but not for their instances - because instances do not trigger the __getattr__ on the metaclass:
class Pipeable(type):
_classes = {}
def __new__(metacls, name, bases, namespace, **kwds):
cls = type.__new__(metacls, name, bases, namespace)
metacls._classes[name] = cls
return cls
def __getattr__(cls, attr):
classes = cls.__class__._classes
if attr not in classes:
raise AttributeError
def pipe_within(*args, **kwargs):
return cls(*args, op=classes[attr], **kwargs)
print('piping...')
return pipe_within
def __dir__(cls):
regular = super().__dir__()
return sorted(regular + list(cls.__class__._classes.keys()))
class Op(metaclass=Pipeable):
def __init__(self, op=None):
if op is not None:
print('piped!')
self.op = op
Op.Op()
(Note as well, that over time I picked this parameter naming convention to use on metaclasses - as most their methods take the class created with them in place of what is the "self" in ordinary classes, I find this naming easier to follow. It is not mandatory, not necessarily "correct", though)
But then, we can make it work for instances by creating the __dir__ and __getattr__ directly on the created classes as well. The catch with that is that the class you are creating already have a __getattr__ or custom __dir__, even in their super-classes, those have to be wrapped. And then, we don't want to re-wrap our own __dir__ and __getattr__, so some extra-care:
class Pipeable(type):
_classes = {}
def __new__(metacls, name, bases, namespace, **kwds):
cls = type.__new__(metacls, name, bases, namespace)
metacls._classes[name] = cls
original__getattr__ = getattr(cls, "__getattr__", None)
if hasattr(original__getattr__, "_metapipping"):
# Do not wrap our own (metaclass) implementation of __getattr__
original__getattr__ = None
original__dir__ = getattr(cls, "__dir__") # Exists in "object", so it is always found.
# these two functions have to be nested so they can get the
# values for the originals "__getattr__" and "__dir__" from
# the closure. These values could be set on the class created, alternatively.
def __getattr__(self, attr):
if original__getattr__:
# If it is desired that normal attribute lookup have
# less precedence than these injected operators
# move this "if" block down.
try:
value = original__getattr__(self, attr)
except AttributeError:
pass
else:
return value
classes = self.__class__.__class__._classes
if attr not in classes:
raise AttributeError
def pipe_within(*args, **kwargs):
return cls(*args, op=classes[attr], **kwargs)
print('piping...')
return pipe_within
__getattr__._pipping = True
def __dir__(self):
regular = original__dir__(self)
return sorted(regular + list(self.__class__.__class__._classes.keys()))
__dir__.pipping = True
if not original__getattr__ or not hasattr(original__getattr__, "_pipping"):
cls.__getattr__ = __getattr__
if not hasattr(original__dir__, "_pipping"):
cls.__dir__ = __dir__
return cls
def __getattr__(cls, attr):
classes = cls.__class__._classes
if attr not in classes:
raise AttributeError
def pipe_within(*args, **kwargs):
return cls(*args, op=classes[attr], **kwargs)
print('piping...')
return pipe_within
__getattr__._metapipping = True
def __dir__(cls):
regular = super().__dir__()
return sorted(regular + list(cls.__class__._classes.keys()))
class Op(metaclass=Pipeable):
def __init__(self, op=None):
if op is not None:
print('piped!')
Op().Op()
So, this ended up being lengthy - but it "does the right thing", by ensuring all classes and instances in the hierarchy can see each other, regardless of creation order.
Also, what make up for the complexity is correctly wrapping other possible customizations of __getattr__ and __dir__ in the class hierarchy - if you don't get any customization of those, this can be an order of magnitude simpler:
class Pipeable(type):
_classes = {}
def __new__(metacls, name, bases, namespace, **kwds):
cls = type.__new__(metacls, name, bases, namespace)
metacls._classes[name] = cls
def __getattr__(self, attr):
classes = self.__class__.__class__._classes
if attr not in classes:
raise AttributeError
def pipe_within(*args, **kwargs):
return cls(*args, op=classes[attr], **kwargs)
print('piping...')
return pipe_within
def __dir__(self):
regular = original__dir__(self)
return sorted(regular + list(self.__class__.__class__._classes.keys()))
cls.__getattr__ = __getattr__
cls.__dir__ = __dir__
return cls
def __getattr__(cls, attr):
classes = cls.__class__._classes
if attr not in classes:
raise AttributeError
def pipe_within(*args, **kwargs):
return cls(*args, op=classes[attr], **kwargs)
print('piping...')
return pipe_within
def __dir__(cls):
regular = super().__dir__()
return sorted(regular + list(cls.__class__._classes.keys()))
To get into work, descriptor must be class attribute, not that of instance.
This code does what was desired.
class Pipeable(type):
_instances = {}
def __new__(cls, name, bases, namespace, **kwds):
namespace.update(cls._instances)
instance = type.__new__(cls, name, bases, namespace)
cls._instances[name] = instance
for inst in cls._instances:
setattr(inst, name, instance)
return instance
def __get__(self, instance, owner):
def pipe_within(*args, **kwargs):
return self(*args, op=instance, **kwargs)
print('piping...')
return pipe_within
class Op(metaclass=Pipeable):
def __init__(self, op=None):
if op is not None:
print('piped!')
self.op = op
Op().Op()

Doesn't create a database table from my model baseclass

I'm trying to build a logging application that stores date, exercise type, duration and comments in a database. It renders the form as i expect it but it does not create the database table from my base class. I just got stuck and hope anyone can help me what's going wrong.
CHOICES = [
(None, 'Choose Exercise'),
('Aerobics', 'Aerobics'),
('Box & Kick', 'Box & Kick'),
('Circle Training', 'Circle Training'),
('Core', 'Core'),
('Afrodance', 'Afro Dance'),
('HIT', 'HIT'),
('StepUp', 'StepUp'),
('Zumba', 'Zumba')]
class AerobicExercise(models.Model):
date = models.DateField(default='YYYYMMDD')
duration = models.DurationField()
comment = models.TextField(blank=True)
exercise = models.CharField(choices=CHOICES, max_length=20)
def __str__(self):
return self.exercise
class SplitDurationWidget(forms.MultiWidget):
def __init__(self, attrs=None):
widgets = (forms.NumberInput(attrs=attrs),
forms.NumberInput(attrs=attrs),
forms.NumberInput(attrs=attrs))
super(SplitDurationWidget, self).__init__(widgets, attrs)
def decompress(self, value):
if value:
hours = value.seconds // 3600
minutes = (value.seconds % 3600) // 60
seconds = value.seconds % 60
return [int(value.days), int(hours), int(minutes), int(seconds)]
return [0, 0, 0, 0]
class Duration(MultiValueField):
widget = SplitDurationWidget
def __init__(self, *args, **kwargs):
fields = (
forms.IntegerField(),
forms.IntegerField(),
forms.IntegerField(),
)
super(Duration, self).__init__(
fields=fields,
require_all_fields=True, *args, **kwargs
)
def compress(self, data_list):
if len(data_list) == 3:
return timedelta(
hours=int(data_list[0]),
minutes=int(data_list[1]),
seconds=int(data_list[2])
)
else:
return timedelta(0)
class AerobicForm(ModelForm):
def __init__(self, *args, **kwargs):
super(AerobicForm, self).__init__(*args, **kwargs)
self.fields['duration'] = Duration()
date = forms.DateField(initial=datetime.date.today())
class Meta:
model = AerobicExercise
fields = '__all__'
localized_fields = ('date',)
widgets = {
'comment': Textarea(attrs={'placeholder': 'The highlight of this workout was...'}),
}

Resources