I have function with signal:
#receiver(post_save, sender=Task)
def my_handler():
executor = User.objects.filter(user_type='Executer')
executor.balance += Task.money
executor.save()
My function should add money to executor after task added. But it gives mistake like:
Internal Server Error: /api/v1/tasks/
Traceback (most recent call last):
...
File "/home/k/pro/freelance-django/free/lib/python3.5/site-packages/django/db/models/fields/__init__.py", line 1853, in get_prep_value
return int(value)
ValueError: invalid literal for int() with base 10: 'Executer'
[20/Sep/2017 14:00:30] "POST /api/v1/tasks/ HTTP/1.1" 500 188088
User class looks like:
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
CUSTOMER = 1
EXECUTER = 2
USER_TYPES = (
(CUSTOMER, 'Customer'),
(EXECUTER, 'Executer'),
)
user_type = models.IntegerField(choices=USER_TYPES, default=EXECUTER, verbose_name='Тип пользователя')
balance = models.DecimalField(decimal_places=2, max_digits=7, default=0, verbose_name='Баланс')
def __str__(self):
return self.username
Task class from task.models is:
class Task(models.Model):
title = models.CharField(max_length=255, verbose_name='Заголовок')
description = models.CharField(max_length=255, verbose_name='Описание')
money = models.DecimalField(max_digits=7, decimal_places=2, default=0, verbose_name='Цена')
assignee = models.ForeignKey('users.User', related_name='assignee', null=True, verbose_name='Исполнитель')
created_by = models.ForeignKey('users.User', related_name='created_by', verbose_name='Кем был создан')
How should I make it work?
U don't have one object but objects so you need literal on them or do update(). The best option is use F expression which has a good performance because its executed on DB:
from django.db.models import F
#receiver(post_save, sender=Task)
def my_handler(sender, instance, **kwargs):
User.objects.filter(user_type=User.EXECUTER).update(balance=F('balance') + instance.money)
This update all records where user_type is Executer and update them balance in one query.
Django docs update
F expressions
Your user_type field is IntegerField and in your choices you have string value so u need change it to something like this:
class User(AbstractUser):
CUSTOMER = 1
EXECUTER = 2
USER_TYPES = (
(CUSTOMER, 'Customer'),
(EXECUTER, 'Executer'),
)
user_type = models.IntegerField(choices=USER_TYPES, default=EXECUTER, verbose_name='Тип пользователя')
balance = models.DecimalField(decimal_places=2, max_digits=7, default=0, verbose_name='Баланс')
Related
I want to set Default value in my table, which must be the primary key of the admin of user_auth_model , But its showing me this error
class department(models.Model):
dept_id = models.AutoField(primary_key=True)
dept_name = models.CharField(max_length=100)
adid = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, null=False, default='admin')
def __str__(self):
return self.dept_name
Here is the Error when i save it
ValueError: invalid literal for int() with base 10: 'admin'
You can make a callable and let that callable link it to the admin:
from django.contrib.auth import get_user_model
def default_admin_user():
if hasattr(default_user, 'admin'):
return default_user.admin
else:
default_user.admin = result = get_user_model().objects.get(username='admin')
return result
class department(models.Model):
# …
adid = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.DO_NOTHING,
default=default_admin_user
)
I am trying to find the time difference between clock_in and clock_out field. For that i have written logic in save method class Timesheet in models.py. The time differnce between will be stored in clock_duration.
But it gives TypeError
Error - while saving data in model
TypeError at /timesheet/clock-out/
can't subtract offset-naive and offset-aware datetimes
Models.py
from django.db import models
from django.conf import settings
class Timesheet(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="timesheetuser")
clock_in = models.DateTimeField(auto_now_add=True)
clock_out = models.DateTimeField(null=True, blank=True)
clock_date = models.DateTimeField(auto_now_add=True)
clock_duration = models.DateField(blank=True, null=True)
def save(self, *args, **kwargs):
if self.clock_in and self.clock_out:
self.clock_duration = self.clock_out - self.clock_in
super(Timesheet, self).save(*args, **kwargs)
class Meta:
db_table = "timesheet"
When a Tasks instance is deleted i want to create a new Instance of Completed Tasks, which stores the deleted task.
Here is my code -
from django.db import models
from django.db.models.signals import post_delete, pre_delete
from django.urls import reverse, reverse_lazy
from django.contrib.auth.models import User
class Tasks(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
TaskName = models.CharField(max_length=100)
Description = models.CharField(max_length=400)
DueDate = models.DateField(help_text="YYYY-MM-DD")
priority = models.IntegerField()
def __str__(self):
return self.TaskName
def get_absolute_url(self):
return reverse('tasks:detail', kwargs={'pk': self.pk})
pre_delete.connect(lambda instance,**kwargs:CompletedTasks.obbjects.create(task = instance))
class CompletedTasks(models.Model):
task = models.ForeignKey(Tasks, on_delete=None)
But , it is not working , instances of CompletedTasks are not being created.
You cannot have a foreign key reference to a non existent object, I suggest that you have a field in the Tasks model that keeps track of the status of the Task.
Something like this:
class Tasks(models.Model):
STATUSES = (
('C','Completed'),
('A', 'Active'),
)
user = models.ForeignKey(User, on_delete=models.CASCADE)
task_name = models.CharField(max_length=100)
description = models.CharField(max_length=400)
due_date = models.DateField(help_text="YYYY-MM-DD")
priority = models.IntegerField()
status = models.CharField(max_length=1, choices=STATUSES, default='A')
I am using the following models for my first django site. But I am currently having problems with how to access the wishes of a user.
class Group(models.Model):
title = models.CharField(max_length=100)
users = models.ManyToManyField(User, related_name='group_users')
description = models.TextField()
added = models.DateTimeField()
owner = models.ForeignKey(User)
def __unicode__(self):
return self.title
class Wish(models.Model):
name = models.CharField(max_length=50)
user = models.ForeignKey(User, related_name='wish_user')
bought = models.IntegerField(default=0)
bought_by = models.ForeignKey(User, related_name='wish_buyer')
added_by = models.ForeignKey(User, related_name='wish_adder')
cost = models.FloatField()
added = models.DateTimeField()
def __unicode__(self):
return self.name
def is_bought(self):
return self.bought % 2 == 1
def is_editable(self):
return self.added >= timezone.now() - datetime.timedelta(hours=1)
When I go to the django shell I get the following:
$ ./manage.py shell
>>> from django.contrib.auth.models import User
>>> from wish.models import Wish, Group
>>> user1 = User.objects.filter(id=1)[0]
>>> user1.group_set.all()
[]
>>> user1.wish_set.all()
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'User' object has no attribute 'wish_set'
>>>
Why doesn't the User object get the wish_set like it does get the group_set ?
That's because you renamed them to wish_user, wish_buyer and wish_adder. Whereas for the group you have wish_set implicity from the owner property and the explicit group_users.
The related_name parameter tells Django how to name the reverse relation. If it's not given it will be <field name>_set
Is it possible to have a field in a Django model which does not get stored in the database.
For example:
class Book(models.Model):
title = models.CharField(max_length=75)
description models.CharField(max_length=255, blank=True)
pages = models.IntegerField()
none_db_field = ????
I could then do
book = Book.objects.get(pk=1)
book.none_db_field = 'some text...'
print book.none_db_field
Thanks
As long as you do not want the property to persist, I don't see why you can't create a property like you described. I actually do the same thing on certain models to determine which are editable.
class Email(EntryObj):
ts = models.DateTimeField(auto_now_add=True)
body = models.TextField(blank=True)
user = models.ForeignKey(User, blank=True, null=True)
editable = False
...
class Note(EntryObj):
ts = models.DateTimeField(auto_now_add=True)
note = models.TextField(blank=True)
user = models.ForeignKey(User, blank=True, null=True)
editable = True
Creating a property on the model will do this, but you won't be able to query on it.
Example:
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
def _get_full_name(self):
return "%s %s" % (self.first_name, self.last_name)
def _set_full_name(self, combined_name):
self.first_name, self.last_name = combined_name.split(' ', 1)
full_name = property(_get_full_name)
full_name_2 = property(_get_full_name, _set_full_name)
Usage:
from mysite.models import Person
a = Person(first_name='John', last_name='Lennon')
a.save()
a.full_name
'John Lennon'
# The "full_name" property hasn't provided a "set" method.
a.full_name = 'Paul McCartney'
Traceback (most recent call last):
...
AttributeError: can't set attribute
# But "full_name_2" has, and it can be used to initialise the class.
a2 = Person(full_name_2 = 'Paul McCartney')
a2.save()
a2.first_name
'Paul'
To make it an instance variable (so each instance gets its own copy), you'll want to do this
class Book(models.Model):
title = models.CharField(max_length=75)
#etc
def __init__(self, *args, **kwargs):
super(Foo, self).__init__(*args, **kwargs)
self.editable = False
Each Book will now have an editable that wont be persisted to the database
If you want i18n support:
# Created by BaiJiFeiLong#gmail.com at 2022/5/2
from typing import Optional
from django.db import models
from django.utils.translation import gettext_lazy as _
class Blog(models.Model):
title = models.CharField(max_length=128, unique=True, verbose_name=_("Title"))
content = models.TextField(verbose_name=_("Content"))
_visitors: Optional[int] = None
#property
def visitors(self):
return self._visitors
#visitors.setter
def visitors(self, value):
self._visitors = value
visitors.fget.short_description = _("Visitors")