Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django model method with self instance

I am trying to move some functional logic into a model's method (instead of in the views), where I think it belongs:

class Spans(models.Model):
    snow = models.IntegerField()
    wind = models.IntegerField()
    exposure = models.CharField(max_length=1)
    module_length = models.IntegerField()
    max_roof_angle = models.IntegerField()
    building_height = models.IntegerField()
    importance_factor = models.IntegerField()
    seismic = models.DecimalField(max_digits=4, decimal_places=2)
    zone = models.IntegerField()
    profile = models.CharField(max_length=55)
    tilt_angle = models.IntegerField()
    span = models.DecimalField(max_digits=18, decimal_places=15)

    def get_spans(self, snow_load, wind_speed, module_length):
        """
        Function to get spans.
        """
        spans = self.objects.filter(
            snow=snow_load,
            wind=wind_speed,
            exposure='B',
            module_length__gte=module_length,
            max_roof_angle=45,
            building_height=30,
            importance_factor=1,
            seismic=1.2,
            zone=1,
            profile='worst'
        ).order_by('snow', 'module_length', 'span')
        return spans

However, I am a little unsure how to call it. In the shell I have tried:

>>> possible_spans = Spans.get_spans(0, 85, 54)

or

>>> possible_spans = Spans.get_spans(Spans, 0, 85, 54)

but I get an error:

TypeError: unbound method get_spans() must be called with Spans instance as first argument (got int instance instead) 

or

TypeError: unbound method get_spans() must be called with Spans instance as first argument (got ModelBase instance instead)  

I know I am missing something fundamental in python logic here, but I'm not sure what it is.

Any help would be much appreciated.

like image 494
Darwin Tech Avatar asked Aug 20 '26 07:08

Darwin Tech


1 Answers

Method needs to be called either with the instance, as the method call makes it as the default self arg. For example,

instance = Spans.objects.get(id=1)
instance.get_spans(0, 85, 54)

Or if you can want to call using class itself. You would have to pass the instance manually

instance = Spans.objects.get(id=1)
Spans.get_spans(instance, 0, 85, 54)

Update: What you are looking for could be achieved using a static method

@staticmethod
def get_spans(snow_load, wind_speed, module_length):
        """
        Function to get spans.
        """
        spans = Spans.objects.filter(
            snow=snow_load,
            wind=wind_speed,
            exposure='B',
            module_length__gte=module_length,
            max_roof_angle=45,
            building_height=30,
            importance_factor=1,
            seismic=1.2,
            zone=1,
            profile='worst'
        ).order_by('snow', 'module_length', 'span')
        return spans

Now you could directly do,

Spans.get_spans(0, 85, 54)
like image 134
Raunak Agarwal Avatar answered Aug 22 '26 20:08

Raunak Agarwal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!