What i am trying to do - is to save post to the model with custom conditions. But each time im trying to save - i receive this error django.db.utils.IntegrityError: null value in column violates not-null constraint
So far, i have tried editing my models, and adding null=True in parameters, but it doesn't seem to help. So what is the best way to solve the problem here? Also have to mention that it doesnt save event_code at all. But even if i will enter that code by hand - it still will give me "Connection closed by server." Also i dont know what this exactly means: Exception Location: /usr/local/lib/python3.11/site-packages/redis/asyncio/connection.py,
serialier.py:
class EventSerializers(serializers.ModelSerializer):
class Meta:
model = Events
fields = ["cam_id", "vehicle_plate", "is_recognition", "is_confirmation", "vehicle_plate", "transit_block_time_min"]
def save(self, **kwargs):
instance = super().save(**kwargs)
is_recognition = instance.is_recognition
is_confirmation = instance.is_confirmation
vehicle_plate = instance.vehicle_plate
if CarParkItem.objects.filter(vehicle_plate=vehicle_plate).exists():
instance.event_code = 1008
elif BlackListItem.objects.filter(vehicle_plate=vehicle_plate).exists():
instance.event_code = 1004
elif is_recognition == False:
instance.event_code = 1003
elif is_recognition == True and is_confirmation == False:
instance.event_code = 1006
elif is_recognition == True and is_confirmation == True:
instance.event_code = 1007
instance.save()
return instance
I have read about different approaches, but still dont know where and how to do it the best.
models that are used for it:
class BlackListItem(models.Model):
vehicle_plate = models.CharField(max_length=999, db_index=True)
valid_until = models.DateTimeField(db_index=True)
description = models.CharField(max_length=999)
def __str__(self):
return self.vehicle_plate
class CarParkItem(models.Model):
vehicle_plate = models.CharField(max_length=999, db_index=True)
valid_until = models.DateTimeField(db_index=True)
description = models.CharField(max_length=999)
def __str__(self):
return self.vehicle_plate
class WorkingMode(models.Model):
PASSMODE_CHOICES = [
('pay_by_hour', 'pay_by_hour'),
('pay_by_interval', 'pay_by_interval'),
('closed', 'closed'),
]
time_lte_hour = models.IntegerField() # <
time_gte_hour = models.IntegerField() # > от
time_lte_min = models.IntegerField() # < до
time_gte_min = models.IntegerField() # >
pass_mode = models.CharField(max_length=999, choices=PASSMODE_CHOICES) # pay_by_hour | pay_by_interval | closed
free_time_min = models.IntegerField(default=0)
interval = models.IntegerField(default=0)
transit_block_time_min = models.IntegerField(default=0, null=True)
price = models.IntegerField(default=0)
entry_fee = models.IntegerField(default=0)
description = models.CharField(max_length=999)
def __str__(self):
return self.pass_mode
and views.py:
class EventModeSet(viewsets.ModelViewSet):
queryset = Events.objects.all()
serializer_class = EventSerializers
it appears that the method def save should have been async as well, because my consumers.py code is also async. So i just added this:
async def save(self, **kwargs):
instance = super().save(**kwargs)
is_recognition = instance.is_recognition
is_confirmation = instance.is_confirmation
vehicle_plate = instance.vehicle_plate
if CarParkItem.objects.filter(vehicle_plate=vehicle_plate).exists():
instance.event_code = 1008
elif BlackListItem.objects.filter(vehicle_plate=vehicle_plate).exists():
instance.event_code = 1004
elif is_recognition == False:
instance.event_code = 1003
elif is_recognition == True and is_confirmation == False:
instance.event_code = 1006
elif is_recognition == True and is_confirmation == True:
instance.event_code = 1007
await asyncio.sleep(0)
instance.save()
As i understand asyncio.sleep(0) is letting other coroutines (from consumers.py) to finish their job before going to next sten instance.save. The fact that other coroutines were not awaited and were not finished - was causing disconnect issue
Related
So I have django model and I want to override save so that it only saves on certain instances. Is there a way to avoid a save from happening if a condition is met? The idea is if certain conditions defined with an if statement aren't met the instance fails to be saved. so for instance if there is not enough waiters we cancel the save, or if there is not enough tables we do the same.
Here's my code:
class Service(models.Model):
id = models.AutoField(primary_key=True)
arrival = models.DateTimeField(auto_now_add=True)
exit = models.DateTimeField(null=True, blank=True)
waiter = models.ForeignKey('Waiter', on_delete=models.CASCADE)
table = models.ForeignKey('Table', on_delete=models.CASCADE)
total_ammount= models.DecimalField(max_digits=15, decimal_places=2)
def save(self, *args, **kwargs):
if self.id == None:
time = datetime.datetime.now()
# check for waiters
waiters = Waiter.objects.select_related().annotate(num_Service=Count('service', filter=Q(service__exit__gt=time))).all()
available_waiters = waiters.filter(num_Service__lt=4)
avalable_waiters_length = len(available_waiters)
# check for tables
tables = Table.objects.select_related().annotate(num_Service=Count('service', filter=Q(service__exit__gt=time))).all()
available_tables = tables.filter(num_Service__lt=1)
avalable_tables_length = len(available_tables)
# return exception if a problem arises
if avalable_tables_length == 0 and avalable_waiters_length == 0:
print("not enough waiters or tables")
if avalable_waiters_length == 0:
print("not enough waiters")
return
if avalable_tables_length == 0:
print("not enough tables")
return
# assign waiter and table
waiter_obj = random.choice(available_waiters)
self.waiter = waiter_obj
table_obj = random.choice(available_tables)
self.table = table_obj
print(time.time())
# check if current time is open
if datetime.time(9,0) < time.time() and time.time()> datetime.time(21, 30):
print("The restaurant is closed")
return
print(time.time())
# add timedelta to init_time
if time.time() < datetime.time(17,0):
print(time + datetime.timedelta(minutes=90))
self.exit = time + datetime.timedelta(minutes=90)
if time.time() > datetime.time(17,0):
self.exit = time + datetime.timedelta(minutes=120)
#finalize pre_save
return super(Service, self).save(*args, **kwargs)
Thank you in advance :)
you should raise an error, like ValidationError for example
I was hoping someone can assist with my issue in that when I used a default callback my 'account_number' field gets an Integrity Error when above 10. Without a default callback, I have no issues and it works.
My Account Model:
def account_number_increment():
last_number = Account.objects.all().order_by("account_number").last()
print("I am the last number")
start_from = AccountSettings.account_number_startfrom
print("I am the start from")
acc_number = '1'
if last_number is None:
print("I am the initiator")
return acc_number
if start_from != '' or start_from is not None:
while Account.objects.all().filter(account_number=start_from).exists():
acc_number_start = int(last_number.account_number) + 1
print("acc # from start from", str(acc_number_start))
return str(acc_number_start)
if last_number:
# last_number.refresh_from_db(fields="account_number")
# last_number.refresh_from_db()
while Account.objects.all().filter(account_number=last_number.account_number).exists():
print("BEFORE addition", last_number.account_number)
new_acc_number = int(last_number.account_number) + 1
print("acc # new number", str(new_acc_number))
return str(new_acc_number)
class Account(models.Model):
name = models.CharField(max_length=100, null=True, blank=True)
address = models.OneToOneField(Address, on_delete=models.SET_NULL, blank=True, null=True,
related_name="account_address")
account_number = models.CharField(max_length=20, default=account_number_increment, null=True, blank=True, unique=True)
# account_number = models.CharField(max_length=20, default='1def') # works with for loop in views.
date_created = models.DateTimeField(auto_now_add=True)
last_modified = models.DateTimeField(auto_now=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
def __str__(self):
return self.name
My Account_Settings Model
class AccountSettings(models.Model):
account_number_startfrom = models.CharField(max_length=100, default='1', blank=True, null=True)
def __str__(self):
return f'{self.job_number_startfrom}, {self.account_number_startfrom}, {self.invoice_number_startfrom}'
My views
def index(request):
if request.method == 'POST':
form1 = AccountForm(prefix='form1', data=request.POST)
form2 = AccountForm(prefix='form2', data=request.POST)
if form1.is_valid() and form2.is_valid():
form1.save()
form2.save()
print("FORMs SAVED")
return redirect(reverse('account:home'))
else:
user1 = CustomUser.objects.create(username='userFirst')
acc1 = Account.objects.create(name='IamUser40000', user=user1)
print('this is the new 1 ----' + str(acc1.pk) + acc1.name + '--------------')
acc11 = Account.objects.get(pk=acc1.pk)
acc2 = Account.objects.create(name='IamUser3000', user=user1)
print('this is the new 2 ----' + str(acc2.pk) + acc2.name +'--------------')
acc22 = Account.objects.get(pk=acc2.pk)
form1 = AccountForm(prefix='form1', instance=acc11)
form2 = AccountForm(prefix='form2', instance=acc22)
# for loop for non default callback
# num = 3
# for i in range(15):
# name = "IAMUSER"+str(i)
# account_number = str(num)
# Account.objects.create(name=name, account_number=account_number, user=user1)
# num = num + 1
# for loop for default with call back
for i in range(15):
name = "IAMUSER" + str(i)
# Account.objects.create(name=name, account_number=account_number_increment(), user=user1)
Account.objects.create(name=name, user=user1)
context = {
'form1': form1,
'form2': form2,
}
return render(request, 'accounts/index.html', context)
The error:
django.db.utils.IntegrityError: duplicate key value violates unique
constraint "account_account_account_number_a5d74cff_uniq" DETAIL: Key
(account_number)=(10) already exists.
I am making a change to a record in a sqlite3 database using Django, and the save() function doesn't seem to work.
I am able to save changes using the graphical admin app however.
Here is the code to the specific model I'm trying to do the save in:
def pickup(self,item):
room_items = Item.objects.filter(roomID = self.room.id)
items = [ri.item_name for ri in room_items]
if item in items:
i = Item.objects.filter(item_name = item)
i[0].roomID = 0
i[0].playerID = self.id
i[0].save()
return f'{self.name} picked up the {item} from {self.room}'
else:
return f"{item} is not in the room. can't pick it up."
the pickup function is in a class called Player. I am updating an Item record. Any solutions?
Here is the entire models file for those who want more context:
from django.db import models
import string,random
class Room(models.Model):
### Field Columns in Room Table ###
room_name = models.CharField(max_length = 64)
description = models.CharField(max_length=500, default=f"No Room description'" )
up = models.CharField(max_length = 64, default="")
down = models.CharField(max_length = 64, default="")
left = models.CharField(max_length = 64, default="")
right = models.CharField(max_length = 64, default="")
def items(self):
items = Item.objects.filter(roomID = self.id)
return [i.item_name for i in items]
def __str__(self):
return self.room_name
class Player(models.Model):
# uuid = models.UUIDField(default=uuid.uuid4, unique=True)
HP = models.IntegerField(default=10)
name = models.CharField(max_length=64, default=f"Room {random.choice(string.ascii_letters)}")#attempting to generate a random room name using ascii_letters from string library and random.choice()
room = models.ForeignKey(Room, on_delete=models.CASCADE, null=True)
# inventory = models.ForeignKey(Inventory)
def inventory(self):
inventory = Item.objects.filter(playerID = self.room.id)
return [i.item_name for i in inventory]
def pickup(self,item):
print(self.room.id)
room_items = Item.objects.filter(roomID = self.room.id)
items = [ri.item_name for ri in room_items]
if item in items:
i = Item.objects.filter(item_name = item)
i[0].roomID = 0
i[0].playerID = self.id
i[0].save()
i[0].persist()
return f'{self.name} picked up the {item} from {self.room}'
else:
return f"{item} is not in the room. can't pick it up."
def drop_item(self,item):
pass
def initialize(self,start):
# start = input(f"{self.name}, you are outside the PyTower. It is a 10 story tower. There is a treasure chest on the top floor. Do you have what it takes to reach the top??? type 'y' to enter Pytower: ")
if start == 'y':
self.room = Room.objects.get(room_name = "Foyer")
print(f"{self.name}, you have now entered the {self.room.room_name}")
return f"{self.name}, you have now entered the {self.room.room_name}"
else:
print(f"{self.name}, when you're ready for Pytower, you may enter!")
return f"{self.name}, when you're ready for Pytower, you may enter!"
print(self.room.description)
print('in room: ', self.room, 'up:',self.room.up, 'down:',self.room.down, 'left:',self.room.left, 'right:', self.room.right)
return self.room
def move(self,way=""):
# print(self.room[way]) #causes error, Room object not subscriptable
# print(way)
# if self.room[way]:
# pass
if way == 'up':
if not self.room.up:
print('you cannot go that way. no rooms there...')
return 'you cannot go that way. no rooms there...'
else:
self.room = Room.objects.get(room_name = self.room.up)
print('in room: ', self.room, 'up:',self.room.up, 'down:',self.room.down, 'left:',self.room.left, 'right:', self.room.right)
return self.room
elif way == 'down':
if not self.room.down:
print('you cannot go that way. no rooms there...')
return 'you cannot go that way. no rooms there...'
else:
self.room = Room.objects.get(room_name = self.room.down)
print('in room: ', self.room, 'up:',self.room.up, 'down:',self.room.down, 'left:',self.room.left, 'right:', self.room.right)
return self.room
elif way == 'left':
if not self.room.left:
print('you cannot go that way. no rooms there...')
return 'you cannot go that way. no rooms there...'
else:
self.room = Room.objects.get(room_name = self.room.left)
print('in room-', self.room, 'up-',self.room.up, 'down-',self.room.down, 'left-',self.room.left, 'right-', self.room.right)
return self.room
elif way == 'right':
if not self.room.right:
print('you cannot go that way. no rooms there...')
return 'you cannot go that way. no rooms there...'
else:
self.room = Room.objects.get(room_name = self.room.right)
print('in room: ', self.room, 'up:',self.room.up, 'down:',self.room.down, 'left:',self.room.left, 'right:', self.room.right)
return self.room
else:
print('you have entered an invalid direction')
return 'you have entered an invalid direction'
def __str__(self):
if not self.room:
return f"{self.name} is outside."
else:
return f"{self.name} in {self.room}"
class Item(models.Model):
item_name = models.CharField(max_length=64)
strength = models.IntegerField(default=5)
item_type = models.CharField(max_length=64,default="weapon")
# playerID = models.ForeignKey(Player, on_delete=models.CASCADE, null=True)
# roomID = models.ForeignKey(Room, on_delete=models.CASCADE, null=True)
playerID = models.IntegerField(blank=True,null=True)
roomID = models.IntegerField(default=1,null=True,blank=True)
def persist(self):
self.save()
def __str__(self):
return self.item_name
To understand why your model isn't saving, you must first understand how querysets are evaluated. Essentially, anytime you iterate over them, or slice them, they will hit the database, however there are caveats to this.
Consider the following abstract example:
def MyModel(models.Model):
column = models.IntegerField()
>>> MyModel.objects.create(column=1)
<MyModel: MyModel object (1)>
>>> queryset = MyModel.objects.all()
Slicing:
>>> queryset[0].column = 2
>>> queryset[0].save()
>>> queryset[0].column
1
In the example above, I took a slice, eg. queryset[0], which hits the database, then immediately took a second slice, to try and save the changes made, which hits the database a second time. Finally, I took a third slice, which hits the database again.
Since the first slice is not the same object as the object I called .save() on, the changes are not reflected in the database. To fix this, simply save a reference to the slice as a variable:
>>> instance = queryset[0]
>>> instance.column = 2
>>> instance.save()
>>> instance.column
2
In this example, I only hit the database twice: once when I call instance = queryset[0], and a second time in instance.save().
Here is the optimized version of your code:
def pickup(self, item_name):
items = Item.objects.filter(item_name=item_name, roomID=self.room.id)
if items:
item = items[0]
item.roomID = 0
item.playerID = self.id
item.save()
return 'message'
return 'no item'
I have period model and this model has a current property that should calculate what period is current.
#with_author
class Period(CommonInfo):
version = IntegerVersionField( )
order_value = models.PositiveSmallIntegerField()
start_date = models.DateField()
end_date = models.DateField()
name = models.CharField(max_length=30)
duration = models.PositiveSmallIntegerField(null=True, blank=True)
is_special = models.BooleanField(default=False)
is_marked = models.BooleanField(default=False)
_is_current = models.NullBooleanField( blank=True, null=True, default=None)
def __unicode__(self):
return u'%s %i %s ' % ("#", self.order_value, self.name)
def _is_current(self):
if self.start_date <= datetime.datetime.now().date() <= self.end_date:
self._is_current = True
else:
self._is_current = False
#property
def is_current(self):
if self._is_current is None:
self._is_current()
return self._is_current
However it is not calculated and I am not getting any error. What I am doing wrong?
First, you need to change the name of your method, because it is the same as one of your database fields (i.e., self._is_current refers to refers to your NullBooleanField and to your method for checking if the period is current. Also, you need to callsave() after updating a field. Try updating (and renaming) your _is_current() method as follows:
def period_is_current(self):
if self.start_date <= datetime.datetime.now().date() <= self.end_date:
self._is_current = True
else:
self._is_current = False
self.save()
This is very confusing. I would just use the property:
#property
def is_current(self):
if not self._is_current:
self._is_current = (self.start_date <= datetime.datetime.now().date() <= self.end_date)
self.save()
return self._is_current
Any help appreciated.
I cannot save parent Program object in admin.py. It only does not work for 1 particular model with inlines, and only with one particular inline. If I take ProgramHotelInline out, I can save the model. If ProgramHotelInline is in inlines for ProgramAdmin, I can't save the model; the terminal output gives: "POST /admin_keywords_submit/ HTTP/1.1" 403 2294
Here is the PageAdmin class:
class ProgramHotelInline(admin.StackedInline):
model = ProgramHotel
extra = 5
def get_formset(self, request, obj=None, **kwargs):
initial = []
formset = super(ProgramHotelInline, self).get_formset(request, obj, **kwargs)
#initial c/i-c/o
if obj:
if request.method == "GET":
for bh in range(0,self.extra):
initial+=[{'check_in':datetime.combine(obj.base_arrival,time(14,00)),
'check_out':datetime.combine(obj.base_departure,time(12,00))}]
self.extra = len(initial)
formset.__init__ = curry(formset.__init__, initial=initial)
return formset
def queryset(self, request):
"""
Prefetch info.
"""
qs = super(ProgramHotelInline, self).queryset(request)
return qs.select_related('hotel__organization','roomtype')
program_extra_fieldsets = ((None, {"fields": ("base_arrival","base_departure","program_type","default_commission","content","no_bed_age","free_child_age","short_description","images")}),)
class ProgramAdmin(PageAdmin):
inlines = (CodeInline,ProgramExcursionInline,ProgramTransferInline, ProgramHotelInline,ProgramCommissionInline,ProgramDiscountInline)
fieldsets = deepcopy(PageAdmin.fieldsets) + program_extra_fieldsets
filter_horizontal = ('images', )
admin.site.register(Program,ProgramAdmin)
here are the models:
class ProgramHotel(models.Model):
program = models.ForeignKey(Program,null=True,blank=True)
hotel = models.ForeignKey('tour.Hotel')
roomtype = ChainedForeignKey(
'tour.RoomType',
chained_field="hotel",
chained_model_field="hotel",
show_all=False,
auto_choose=False,blank=True,null=True,help_text="<span style='color:blue'>null means no bed</span>")#null stands for (child) with no bed!
check_in = models.DateTimeField(default=default_ci_time)
check_out = models.DateTimeField(default=default_co_time)
#max_age = models.IntegerField(default=0)
pax_per_room = models.SmallIntegerField()
exb = models.BooleanField(default=False)
bb = models.BooleanField(default=False)
turn = models.SmallIntegerField(default = 1)#if we have more than one stopping, first stopping - turn=1,2nd - turn=2 etc
USD = '$'
KRW = unichr(8361)
CURRENCY_CHOICES = (
(USD, 'USD'),
(KRW, 'KRW'),
)
currency = models.CharField(default = "$",max_length=1,choices=CURRENCY_CHOICES)
price = models.DecimalField('price per pax, including comm.',decimal_places=0, max_digits=21, default = 0)#in USD
def __unicode__(self):
if self.roomtype:
if self.pax_per_room == 2:
rt= u"\u00BD%s" % (self.roomtype.roomtype)
elif self.pax_per_room == 3:
rt= u"\u2153%s" % (self.roomtype.roomtype)
elif self.pax_per_room == 4:
rt= u"\u00BC%s" % (self.roomtype.roomtype)
elif self.pax_per_room == 5:
rt= u"\u2155%s" % (self.roomtype.roomtype)
elif self.pax_per_room == 1:
rt= u"%s, single occupancy" % (self.roomtype.roomtype)
elif self.pax_per_room > 5:
rt= u"1/%s %s" % (self.pax_per_room,self.roomtype.roomtype)
else:
rt= u"%s" % (self.roomtype.roomtype)
else:
rt="no bed"
bb = u", breakfast" if self.bb else u", NO BREAKFAST"
exb = u", +extra bed" if self.exb else u""
return u"%s: %s, %s ~ %s%s%s; %s%s" % (self.hotel.organization,rt,self.check_in.strftime("%d %B %Y"), self.check_out.strftime("%d %B %Y"),bb,exb,self.price,self.currency)
class Meta:
unique_together = (("program", "turn","hotel","roomtype","check_in","pax_per_room","exb","bb"),)
class Program(Page,RichText):
def default_commission_default():
l = list(DynamicParameter.within_dates.within_dates(datetime.today()))[:1]
dynamic = l[0]
return dynamic.default_agent_commission
def no_bed_age_default():
l = list(DynamicParameter.within_dates.within_dates(datetime.today()))[:1]
dynamic = l[0]
return dynamic.default_no_bed_age
def free_child_age_default():
l = list(DynamicParameter.within_dates.within_dates(datetime.today()))[:1]
dynamic = l[0]
return dynamic.default_free_child_age
program_type = models.ManyToManyField(ProgramType)
images = models.ManyToManyField(PicasaGallery,null=True, blank=True)
short_description = RichTextField(max_length=250,default = "")
#excursions, transfers, hotels - just a template; actuals are in Code
hotels = models.ManyToManyField('tour.Hotel', through='ProgramHotel')
transfers = models.ManyToManyField('misc.Transfer', through='ProgramTransfer')
excursions = models.ManyToManyField("tour.Excursion", through='ProgramExcursion')
commission = models.ManyToManyField(Customer, through='ProgramCommission')
default_commission = models.DecimalField('agent commission',decimal_places=3, max_digits=4, default = default_commission_default)
base_arrival = models.DateField()
base_departure = models.DateField()
no_bed_age = models.SmallIntegerField(default=no_bed_age_default) #UP TO THIS AGE ALLOWED TO HAVE NO BED
free_child_age = models.SmallIntegerField(default=free_child_age_default) #NO BED+BREAKFAST FREE, IF ADULTS HAVE BREAKFAST; no tickets!
discount = models.ManyToManyField(Discount, through='ProgramDiscount')
def save(self, *args, **kwargs):
''' On save, make invisible in left and foot menu
SET COMMISSION, IF DEFINED
add bonus for a company, if any
'''
self.in_menus = '1'
super(Program, self).save(*args, **kwargs)
if self.default_commission:
for customer in Customer.objects.filter(customer_type="AGENT"):
try:
pc = ProgramCommission.objects.get(program=self,customer=customer)
except ObjectDoesNotExist:
pc = ProgramCommission(program=self,customer=customer, commission=self.default_commission)
#print pc
if not pc.id:
if pc.customer.organization=="Private Customer":
pc.commission = 0.00
try:
customer_comm = CustomerCommission.within_dates.within_dates(self.base_arrival).get(customer=customer).bonus_commission
if customer_comm >0:
pc.commission = pc.commission + customer_comm
except ObjectDoesNotExist:
pass
pc.save()
def __unicode__(self):
return u"%s" % (self.title)
def groupcode(self):
"""
return filtered set - only code.group=True
"""
return self.code_set.filter(group=True,arr_date__gte=datetime.today())
def distincthotel(self):
"""
return filtered set - only distinct hotels
"""
return self.programhotel_set.distinct('hotel')
def get_admin_url(self):
return urlresolvers.reverse("admin:%s_%s_change" %
(self._meta.app_label, self._meta.module_name), args=(self.id,))
class Meta:
ordering = ['title']
Found the source of mistake: that was outdated django-smart-selects. After update it works again.