Django won't syncdb after adding a method to a model - python

When I add the check_stats() method manage.py hangs. The within_range() and light_check() functions are imported from a custom library. I've tried running syncdb with verbosity, but I receive no errors. I'm unable to stop the process with ctrl+c and have to close the terminal window. After this I'm no longer able to run any commands from manage.py without getting the same problem. I had another function in another file that did the same exact thing, but I wanted to use a method instead. I've deleted the db and tried syncing again and no db even gets created unless I remove that method.
class PlotZone(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=40, blank=True)
plot_comments = models.CharField(max_length=500, blank=True)
current_temp = models.IntegerField(default=0)
current_humid = models.IntegerField(default=0)
light_start = models.TimeField(blank=True, null=True)
light_stop = models.TimeField(blank=True, null=True)
light_status = models.BooleanField(default=True)
goal_temp = models.IntegerField(default=0)
goal_humid = models.IntegerField(default=0)
humid_alert = models.NullBooleanField(default=False)
temp_alert = models.NullBooleanField(default=False)
light_alert = models.NullBooleanField(default=False)
alert_status = models.NullBooleanField(default=False)
humid_fail_limit = models.IntegerField(default=0)
temp_fail_limit = models.IntegerField(default=0)
def check_stats(self):
if not within_range(self.goal_temp, self.current_temp, self.temp_fail_limit):
self.alert_status = True
elif not within_range(self.goal_humid, self.current_humid, self.humid_fail_limit):
self.alert_status = True
elif not light_check(self, datetime.time()):
self.alert_status = True
def within_range(goal, current, fail_limit):
goal = int(goal*10)
current = int(current*10)
fail_limit = int(fail_limit*10)
lower_range = range((goal-fail_limit), goal+1)
upper_range = range(goal, (goal+(fail_limit+1)))
if (current in lower_range) or (current in upper_range):
return True
else:
return False

Related

Table level logic Django

I have this model:
class Sesion(models.Model):
maq = models.CharField(max_length=25)
ini_sesion = models.DateTimeField(auto_now_add=True)
fin_sesion = models.DateTimeField(null=True, blank=True)
cont_ini_a = models.IntegerField(null=True, blank=True)
con_ini_b = models.IntegerField(null=True, blank=True)
con_fin_a = models.IntegerField(null=True, blank=True)
con_fin_b = models.IntegerField(null=True, blank=True)
#staticmethod
def cierre():
instance = Sesion.objects.filter(fin_sesion__isnull=True).latest('ini_sesion')
sesion_abierta = None
try:
sesion_abierta = Sesion.objects.filter(maq=instance.maq).filter(fin_sesion__isnull=True) \
.filter(ini_sesion__lt=instance.ini_sesion).latest('ini_sesion')
except Exception:
print('Ha ocurrido una excepcion!')
if sesion_abierta:
sesion_abierta.con_fin_a = instance.con_fin_a
sesion_abierta.con_fin_b = instance.con_fin_b
sesion_abierta.fin_sesion = instance.ini_sesion
return sesion_abierta.save()
Now the thing is i can't make it work every time a model instance is saved. I works when it is called from python/django shell
>>> Sesion.cierre()
but not when a model instance is saved and it doesn't work on save() override or signals either. Thx in advance.
Well I will answer the question. Here is what worked:
#receiver(post_save, sender=Sesion)
def cierre(*args, **kwargs):
instance = Sesion.objects.filter(fin_sesion__isnull=True).latest('ini_sesion')
sesion_abierta = None
try:
sesion_abierta = Sesion.objects.filter(maq=instance.maq).filter(fin_sesion__isnull=True) \
.filter(ini_sesion__lt=instance.ini_sesion).latest('ini_sesion')
except Exception:
print('Ha ocurrido una excepcion!')
if sesion_abierta:
sesion_abierta.con_fin_a = instance.con_fin_a
sesion_abierta.con_fin_b = instance.con_fin_b
sesion_abierta.fin_sesion = instance.ini_sesion
sesiĆ³n_abierta.save()
Edit: Note that the "signals" code goes on the same line of indentation as
class Sesion(models.Model):

Django get_or_create() duplicates in db

Using Django 1.11.6, MySql
I`m importing uniq only data rows from CSV file (~530 rows).
After 1st import - all 530 records updated to the DB.
If I import this file 2d time and ~30 last records will be updated to DB.
Get data:
obj.account = int(ready_item[0].replace("\"","").replace("*",""))
pai_obj.reporting_mask = str(ready_item[0].replace("\"","").replace("*",""))
pai_obj.group = ready_item[1].replace("\"","")
pai_obj.location = ready_item[2].replace("\"","")
pai_obj.terminal = ready_item[4].replace("\"","")
pai_obj.settlement_type = ready_item[5].replace("\"","")
pai_obj.settlement_date = datetime_or_none(report_data)
pai_obj.amount = float_or_none(ready_item[6].replace("\"","").replace("$","").replace(",",""))
data.append(pai_obj)
Import vie get_or_create():
for record in data:
Accountmode.objects.get_or_create(
account=record.account,
reporting_mask=record.reporting_mask,
group=record.group,
location=record.location,
terminal=record.terminal,
settlement_type=record.settlement_type,
amount=record.amount,
defaults={'settlement_date': record.settlement_date})
The Model:
class Accountmode(models.Model):
account = models.IntegerField(blank=True, default=0)
reporting_mask = models.IntegerField(blank=False, default=0)
group = models.CharField(max_length=1024, blank=True, null=True)
location = models.CharField(max_length=1024, blank=True, null=True)
settlement_date = models.DateField(null=True)
terminal = models.CharField(max_length=1024, blank=False, null=True)
settlement_type = models.CharField(max_length=1024, blank=False, null=True)
amount = models.DecimalField(max_digits=25, decimal_places=2)
created_date = models.DateTimeField(default=datetime.now, blank=True)
As I know, get_or_create() should check if data already exist first and create new record if Not. Why get_or_create() pass some records?
The case was about Flout values with +3 symbols after come (12,012).
Those values were duplicating each time the user import same file.
Next solution was found:
1. Save amount and other values at str during file rows parsing.
obj.account = int(ready_item[0].replace("\"","").replace("*",""))
pai_obj.reporting_mask = str(ready_item[0].replace("\"","").replace("*",""))
pai_obj.group = ready_item[1].replace("\"","")
pai_obj.location = ready_item[2].replace("\"","")
pai_obj.terminal = ready_item[4].replace("\"","")
pai_obj.settlement_type = ready_item[5].replace("\"","")
pai_obj.settlement_date = datetime_or_none(report_data)
pai_obj.amount = *str*(ready_item[6].replace("\"","").replace("$","").replace(",",""))
data.append(pai_obj)

Did I set this up correctly?

I'm asking if I set up the create method up correctly. Or does it need to be added for the other two models as well? How would this be changed?
class PointModel(models.Model):
x = models.IntegerField()
y = models.IntegerField()
index = models.IntegerField()
class DatetimeRangeModel(models.Model):
start_datetime = models.CharField(max_length=14)
end_datetime = models.CharField(max_length=14)
class PlanModel(models.Model):
data_number = models.IntegerField()
data_datetime_range = models.ForeignKey(DatetimeRangeModel, blank=True, null=True, on_delete=models.SET_NULL)
data_polygon = models.ForeignKey(PointModel, blank=True, null=True, on_delete=models.SET_NULL)
#classmethod
def create(cls, data_number, data_datetime_range, data_polygon):
plan = cls(data_number=data_number, data_datetime_range = data_datetime_range,
data_polygon=data_polygon)
return plan
EDIT: I change the structure which fixed the undefined and added some logic that prevents the PlanModel from being deleted with the "blank=True, null=True, on_delete=models.SET_NULL"
Does this look right?
see the docs for creating objects
#classmethod
def create(cls, title):
book = cls(title=title)
# do something with the book
return book
there's no much reason to add those unless you have something to add there on the # do something with the book line
EDIT: instead of calling create you're usually do:
plan = PlanModel(data_number=1, ....)
plan.save()
or sometimes:
plan = PlanModel()
plan.data_number=1
...
plan.save()

Django Many To Many Complaining about PrimaryKey

I have three models that are related. The first is called DayOfWeek, which is juts a day label and number. It looks like this:
class DayOfWeek(models.Model):
day = models.IntegerField()
label = models.CharField(max_length='20')
def __str__(self):
return self.label
This class is populated using a fixture every time I syncdb.Next, I have an event model, it looks like this:
class Event(AnnouncementBase, Location):
cost = CurrencyField(decimal_places=2, max_digits=10, blank=True, default=0.00)
start_date = models.DateField(default = datetime.now().date())
start_time = models.TimeField(default = datetime.now().time())
end_date = models.DateField(blank=True, default=None, null = True)
end_time = models.TimeField(blank=True, default=None, null = True)
Finally, there is a recurrence. It has an event and is used to schedule the event for recurring events. It looks like this:
class Recurrence(models.Model):
event = models.ForeignKey(Event, related_name='event')
repeats = models.CharField(max_length = 50, choices = EVENT_REPEAT_CHOICES)
repeat_every = models.IntegerField(default = 1)
repeat_on = models.ManyToManyField(DayOfWeek, blank=True, null=True)
repeat_by = models.CharField(max_length = 50, choices = EVENT_REPEAT_BY_CHOICES, blank=True)
repeat_by_day_of_month = models.IntegerField(default = 0, blank=True)
repeat_ends = models.CharField(max_length = 50, choices = EVENT_REPEAT_END_CHOICES)
end_occurrences = models.IntegerField(default = 0, blank=True)
repeat_end_date = models.DateField(blank=True, default=None, null = True)
past_event_count = models.IntegerField(default=0, blank=True)
scheduled_events = models.ManyToManyField(Event, blank=True, default=None, related_name = 'scheduled_events')
is_active = models.BooleanField(blank=True, default=True)
def save(self, force_insert=False, force_update=False, using=None):
"""Overridden to create events the first time."""
self.full_clean()
#First do normal save so the data is there for the even scheduler.
self.save_base(force_insert=force_insert, force_update=force_update, using=using)
#If nothing is scheduled yet, schedule the first batch
if self.scheduled_events.count() == 0 and self.past_event_count == 0:
self.scheduleEvents()
def clean(self):
#repeat on weekly
if self.repeat_every < 1:
raise ValidationError('Repeat every must be at least 1.')
#weekly
if self.repeats == EVENT_REPEAT_CHOICES[1][0]:
#look for missing stuff
if not self.repeat_on:
raise ValidationError('Missing repeat on.')
Finally, I have a unit test that checks this works ok it looks like this:
def test_weekly_mon_wed_fri_occurrence(self):
event = Event()
event.start_date = date(year=2012, month=1, day=2)
event.start_time = time(hour=13, minute=30)
event.save()
recurrence = Recurrence()
recurrence.repeats = EVENT_REPEAT_CHOICES[1][0]
recurrence.repeat_on = (EVENT_DAY_CHOICES[1][0], EVENT_DAY_CHOICES[3][0], EVENT_DAY_CHOICES[5][0])
recurrence.repeat_ends = EVENT_REPEAT_END_CHOICES[0][0]
recurrence.event = event
nextEvent = recurrence.getNextEvent(event)
self.assertEquals(date(year=2012, month=1, day=4), nextEvent.start_date)
self.assertEquals(event.start_time, nextEvent.start_time)
nextNextEvent = recurrence.getNextEvent(nextEvent)
self.assertEquals(date(year=2012, month=1, day=6), nextNextEvent.start_date)
self.assertEquals(event.start_time, nextNextEvent.start_time)
Whenever the test is run it fails, with the following exception.
ValueError: 'Recurrence' instance needs to have a primary key value before a many-to-many relationship can be used.
The error happens on the line if self.repeat_on in the clean method.
I want repeat_on to be optional, only some types of recurrences need it. How do I make this work? What am I missing that is causing it to fail?
You need to call recurrence.save() before assigning Many2Many relationships. In your code you do
recurrence.repeat_on = (EVENT_DAY_CHOICES[1][0], EVENT_DAY_CHOICES[3][0], EVENT_DAY_CHOICES[5][0])
without saving the recurrence first. Because its not saved, recurrence does not have primary key generated yet, and Django ORM doesn't know what to insert as a foreign key into the M2M table.

Specific Quote Issue

Here is my problem. I have a model Project, that has a quote field in it. When a new instance of project is created I need to append the last 2 digits of the year plus a hyphen onto the start of the "quote" field. Ex. 2010 = "10-". Im just not quite sure how to start it?
As of right now I have hard coded in "10-" in as a pre-quote field, but I do not want to have to do that.
models.py
class Project(models.Model):
client = models.ForeignKey(Clients, related_name='projects')
created_by = models.ForeignKey(User, related_name='created_by')
#general information
proj_name = models.CharField(max_length=255, verbose_name='Project Name')
pre_quote = models.CharField(max_length=3,default='10-')
quote = models.IntegerField(max_length=10, verbose_name='Quote #', unique=True)
desc = models.TextField(verbose_name='Description')
starts_on = models.DateField(verbose_name='Start Date')
completed_on = models.DateField(verbose_name='Finished On')
Anyone have to do this before? Or have any suggestions?
Try this:
def save(self):
today = datetime.date.today()
self.quote = "%s-%s" % (str(today.year)[2:4], self.quote)
Assuming you imported datetime.
Your existing quote field is set as an integer. You will need to set this as a text field. Once you do that, you can override the save() function to prepend "10-" to the field.
class Project(models.Model):
client = models.ForeignKey(Clients, related_name='projects')
created_by = models.ForeignKey(User, related_name='created_by')
proj_name = models.CharField(max_length=255, verbose_name='Project Name')
quote = models.TextField(max_length=10, verbose_name='Quote #', unique=True)
desc = models.TextField(verbose_name='Description')
starts_on = models.DateField(verbose_name='Start Date')
completed_on = models.DateField(verbose_name='Finished On')
def save(self):
self.quote = "10-" + self.quote

Categories