Doesn't create a database table from my model baseclass - python-3.x

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...'}),
}

Related

How can I connect different class instances based on their ids?

I have the two following classes:
class Position(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField()
price = models.FloatField(blank=True)
created = models.DateTimeField(blank=True)
def save(self, *args, **kwargs):
self.price = self.product.price * self.quantity
return super().save(*args, **kwargs)
def __str__(self):
return f"id: {self.id}, product: {self.product.name}, quantity: {self.quantity}"
class Sale(models.Model):
transaction_id = models.CharField(max_length=12, blank=True)
positions = models.ManyToManyField(Position)
total_price = models.FloatField(blank=True, null=True)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
salesman = models.ForeignKey(Profile, on_delete=models.CASCADE)
created = models.DateTimeField(blank=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return f"Total sales price: ${self.total_price}"
def get_absolute_url(self):
return reverse('sales:detail', kwargs={'pk': self.pk})
def save(self, *args, **kwargs):
if self.transaction_id == '':
self.transaction_id = generate_code()
if self.created is None:
self.created = timezone.now()
return super().save(*args, **kwargs)
def get_position(self):
return self.positions.all()
How can I relate each position instance with its related sale instance?
I've tried implementing this method:
def get_sales_id(self):
sale_obj = self.sale_set.first()
return sale_obj.id
but in this case I will always get the first id of a determined position occurrence.
Exaple:
pos1: id 1, product, quanity, price ...
pos2: id 2, product, quantity, price ...
sale1: pos 1, pos 2 ...
sale2: pos 1, pos3 ...
When I try to merge these, based on the sale id, I get:
pos1: id 1, ... , sale_id 1
pos1: id 1, ... , sale_id 1 <= when it should be 2!
I've tried to set up this filter, but I just can't wrap my head around how to make it work:
def get_id(self):
related_sale_obj = Sale.objects.filter(positions = self)
#related_id = related_obj.id
#sales_id_prefetched = self.sale_set.only('Position').explain()
return related_sale_obj
If you have any idea on how I could fix this, it'd be much appreciated.
Have a nice day

Why the type of a parameter of a function in a class would change into list?

class Employee:
num_of_emps = 0
raise_amount = 1.04
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.pay = pay
self.email = first + last + '#gmail.com'
Employee.num_of_emps += 1
def fullname(self):
return f'I am {self.first} {self.last}'
def apply_raise(self):
self.pay = int(self.pay * Employee.raise_amount)
#classmethod
def set_raise_amt(cls, amount):
cls.raise_amount = amount
#classmethod
def from_string(cls, emp_str):
first, last, pay = emp_str.split('-')
return cls(first, last, pay)
#staticmethod
def is_workday(day):
if day.weekday() == 5 or day.weekday() == 6:
return False
return True
class Developer(Employee):
raise_amount = 1.50
def __init__(self, first, last, pay, prog_lang):
super().__init__(first, last, pay)
self.prog_lang = prog_lang
class Manager(Employee):
def __init__(self, first, last, pay, employees=None):
super().__init__(first, last, pay)
if employees is None:
self.employees = []
else:
self.employees = employees
def add_emp(self,emp):
if emp not in self.employees:
self.employees.append(emp)
def remove_emp(self,emp):
if emp in self.employees:
self.employees.remove(emp)
def print_emps(self):
for emp in self.employees:
print('--->', emp.full_name())
dev_1 = Developer('John','Doe',30000, 'Python')
dev_2 = Developer('Emily','Smith',23000, 'Java')
# print(help(Developer))
print(dev_1.email)
print(dev_2.email)
print(dev_1.pay)
dev_1.apply_raise()
print(dev_1.pay)
mgr_1 = Manager('Sarah','Smith',34000, [dev_1])
print(type(mgr_1.employees))
print(mgr_1.employees)
print(type(dev_1))
print(type([dev_1]))
print([dev_1])
mgr_1.print_emps()
I recently studied this code on youtube. So basically this code started with a class named 'Employee' at the beginning, and then a subclass called 'Developer' was created. I still able to catch up with the logic behind the code at the moment, but after another subclass called 'Manager' was created, I lost.
I don't know why the parameter,'employees' in the class 'Manager' would suddenly become a list in the end
And I also don't know why the for loop could be able to run
Please help, thank you so much
mgr_1 = Manager('Sarah','Smith',34000, [dev_1])
first='Sarah', last='Smith', pay=34000, employees=[dev_1]
Your parameter is an list

how solve django create model class dynamically

When dynamically creating and generating Model class, modify some
properties, fill in the information required by the sub-table, the
first time can return the normal result, the second result error,
after the analysis of the second result field to retain the first
table name:
class Object:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def _model_new(cls, *args, **kwargs):
return cls(*args, **kwargs)enter code here
class ShardModel(object):
_shard_db_models = {}
temp_class = []
def __new__(cls, *args, **kwargs):
shard_key = kwargs.pop('shard_key', 0) % cls.Config.table_num
model_name = cls.__name__
model_name += '_%s' % shard_key
model_class = cls._shard_db_models.get(model_name)
if model_class is not None:
return model_class
# Deep copy attrs
attrs = dict()
attrs.update(cls.__dict__)
if 'objects' in attrs:
attrs['objects'] = attrs['objects'].__class__()
# Set table name with shard_key
meta = Object(**cls.Meta.__dict__)
meta.db_table = meta.db_table % shard_key
meta.abstract = False
attrs['Meta'] = meta
attrs['new'] = classmethod(_model_new)
attrs['__module__'] = cls.__name__
cursor = connection.cursor()
tables = [table_info.name for table_info in connection.introspection.get_table_list(cursor)]
# Create model class dynamically
model_class = type(model_name, tuple([models.Model] + list(cls.__bases__[1:])), attrs)
print(model_class)
if meta.db_table not in tables:
for cmd in ('makemigrations', 'migrate'):
exec_command(cmd, meta.app_label)
cls._shard_db_models[model_name] = model_class
return model_class
this is my model
class Nice(ShardModel):
user_id = models.IntegerField()
user_name = models.CharField(max_length=256)
password = models.CharField(max_length=256)
class Config:
table_num = 3
class Meta:
app_label = 'Test'
db_table = 'test_%s'
abstract = True
this my view
def NiceView(request):
user_id = int(request.GET.get('user_id'))
user = Nice(shard_key=user_id).objects.get(user_id=user_id)
return HttpResponse(json.dumps(model_to_dict(user)))
Here are the two times test results
url:http://127.0.0.1:8000/test?user_id=7
results:{"id": 2, "user_id": 7, "user_name": "ni", "password": "hao"};url:http://127.0.0.1:8000/test?user_id=5;error:(1054, "Unknown column 'test_1.user_id' in 'field list'")

Django ModelManager not saving the model instance correctly

I am working on an ecommerce project but my OrderManager() class does not saving the instance(i think)
When i am clicking on BOOK button i am getting this error which is defined in my view
order_amount = order_obj.total * 100
AttributeError: 'NoneType' object has no attribute 'total'
But when i refresh the page error goes way and order_obj.total * 100 is calculated, But my question is why i need to refresh the page again and again when i create a new order.
Here is my models.py
class OrderQuerySet(models.query.QuerySet):
def not_created(self):
return self.exclude(status='created')
class OrderManager(models.Manager):
def get_queryset(self):
return OrderQuerySet(self.model, using=self.db)
def create_or_get_order(self, product):
created = None
obj = None
qs = self.get_queryset().filter(product=product, active=True, status='created')
if qs.count() == 1:
obj = qs.first()
else:
self.model.objects.create(product=product)
created = True
return obj, created
class Order(models.Model):
order_id = models.CharField(max_length=120, blank=True)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
total = models.PositiveIntegerField()
active = models.BooleanField(default=True)
objects = OrderManager()
class Meta:
ordering = ['-ordered_on', '-updated']
def __str__(self):
return self.order_id
def check_done(self): # check everything is correct before final checkout
order_id = self.order_id
total = self.total
if order_id and total > 0:
return True
return False
def mark_paid(self):
if self.check_done():
self.status = 'paid'
self.save()
return self.status
def pre_save_create_order_id(sender, instance, *args, **kwargs):
if not instance.order_id:
instance.order_id = unique_order_id_generator(instance)
pre_save.connect(pre_save_create_order_id, sender=Order)
def pre_save_order_total(sender, instance, *args, **kwargs):
"""calculate the product total while clicking on Book Button
(Still booking is not done you just clicked on Book button)"""
instance.total = instance.product.price
pre_save.connect(pre_save_order_total, sender=Order)
Views.py
def checkout_home_view(request, *args, **kwargs):
order_obj = None
order_amount = None
order_currency = None
order_id = None
slug = kwargs['slug']
product = Product.objects.get(slug=slug)
if product is not None:
# ****************** Here is problem ******************************
order_obj, order_create = Order.objects.create_or_get_order(product)
''' HERE I AM GETTING order_obj as None BUT WHEN I REFRESH ERROR GOES WAY '''
print('order_obj', order_obj) # printing None initally
order_amount = order_obj.total * 100
order_currency = 'INR'
order_id = order_obj.order_id
if request.method == 'POST':
'check that booking is done'
is_prepared = order_obj.check_done() # check_done() defined in Order model
if is_prepared:
client = razorpay.Client(auth=("xxx", "xxx"))
payment = client.order.create(dict(amount=order_amount, currency=order_currency))
if payment:
order_obj.mark_paid() # mark_paid() defined in Order model
order_obj.save()
class OrderManager(models.Manager):
...
def create_or_get_order(self, product):
created = None
obj = None
qs = self.get_queryset().filter(product=product, active=True, status='created')
if qs.count() == 1:
obj = qs.first()
else:
# -------------- catch the returned obj and return --------------
obj = self.model.objects.create(product=product)
created = True
return obj, created

I can't figure out what's wrong with the python code below. It keeps giving me Attribute error: 'Dog' object has no attribute '_Dog_name'

class Animal:
__name = None
__height = 0
__weight = 0
__sound = 0
We call a constructor, a constructor is called to setup/initialize an object
def __init__(self, name, height, weight, sound):
self.__name = name
self.__height = height
self.__weight = weight
self.__sound = sound
def set_name(self, name):
self.__name = name
def get_name(self):
return self.__name
def set_height(self, height):
self.__height = height
def get_height(self, height):
return self.__height
def set_weight(self, weight):
self.__weight = weight
def get_weight(self):
return self.__weight
def set_sound(self, sound):
self.__sound = sound
def get_sound(self):
return self.__sound
def get_type(self):
print("Animal")
def toString(self):
return "{} is {} cm tall and {} kilograms in weight and makes the sound {}".format(self.__name, self.__height,
self.__weight, self.__sound)
cat = Animal('Whiskers', 33, 20, 'meow')
print(cat.get_name())
print(cat.toString())
class Dog(Animal):
__owner= ""
def __init__(self,name,height,weight,sound,owner):
self.__owner=owner
super(Dog,self).__init__(name,height,weight,sound)
def set_owner(self,owner):
self.__owner=owner
def get_owner(self):
return self.__owner
def get_type(self):
print("dog")
def toString(self):
return"{} is {} cm tall and weighs {}. He says {} and his owner is {}".format(self.__name,
self.__height,
self.__weight,
self.__sound,
self.__owner)
Spot = Dog("Spot",45,77,"Ruff","Amit")
print(Spot.toString())
Here the class Animal is being called in to use its attributes. I saw this on a tutorial video, it seems to be running fine in the video but not when I try it
The issue is with "name mangling" (c.f. https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references). If you wish to access super class variables with double underscores, you should prefix them with the class name:
def toString(self):
return"{} is {} cm tall and weighs {}. He says {} and his owner is {}".\
format(self._Animal__name,
self._Animal__height,
self._Animal__weight,
self._Animal__sound,
self.__owner)
Alternatively you could call the getters from Animal such as self.get_name().

Resources