django modelchoicefield select columns - django

I can't figure out how to format the output of a ModelChoiceField when only 2 or 3 columns are selected.
Here is my model:
class ActsIdsModel(models.Model):
releveAnnee = models.IntegerField(max_length=4, blank=False, null=False)
releveMois=models.IntegerField(max_length=2, blank=False, null=False)
noOrdre=models.IntegerField(max_length=2, blank=False, null=False)
...
#many other fields
...
def __unicode__(self):
releveAnnee=vn.variablesNameDic['releveAnnee'] + "=" + str(self.releveAnnee)
releveMois=vn.variablesNameDic['releveMois'] + "=" + str(self.releveMois)
noOrdre=vn.variablesNameDic['noOrdre'] + "=" + str(self.noOrdre)
return releveAnnee + ", " + releveMois + ", " + noOrdre
The code below works but I get all the columns (so not efficient for my purpose):
class ActsAddForm(forms.Form):
actsToValidate=forms.ModelChoiceField(queryset=ActsIdsModel.objects.filter(validated=0))
But the code below does not work:
class ActsAddForm(forms.Form):
actsToValidate=forms.ModelChoiceField(queryset=ActsIdsModel.objects.values("releveAnnee", "releveMois", "noOrdre").filter(validated=0))
How to fix the problem? It seems that when I choose the columns the unicode function of my model is not called anymore. Right?

Use .only() method instead of .values():
https://docs.djangoproject.com/en/1.5/ref/models/querysets/#django.db.models.query.QuerySet.only

Related

How to calculate numbers of days between two dates and subtract weekends DJANGO MODELS

hope you're all fine!
I have a model called Vacation and I'm struggling with one field: days_requested, this field is the number days from vacation_start and vacation_end, it works and gives me an integer as result. The problem I'm facing now is that I need to subtract the weekends (or not count them).
What I have:
vacation_start = '2022-05-20'
vacation_end = '2022-05-24'
days_requested = 5
What I'm trying to have:
vacation_start = '2022-05-20'
vacation_end = '2022-05-24'
days_requested = 3
#21/05 and 22/05 are weekends
Vacation Models:
class Vacation(models.Model):
department = models.ForeignKey(
'departments.Department', on_delete=models.SET_NULL, null=True)
responsible = models.ForeignKey(
User, on_delete=models.SET_NULL, null=True, related_name='responsible_vacation')
status = models.CharField(
max_length=20, choices=STATUS_CHOICES_VACATIONS, default='open')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
created_by = models.ForeignKey(
User, on_delete=models.SET_NULL, null=True, related_name='created_by_vacation')
vacation_start = models.DateField(blank=False)
vacation_end = models.DateField(blank=False)
days_requested = property(
lambda self: (self.vacation_end - self.vacation_start).days + 1
)
def __str__(self):
return str(self.created_by.first_name + ' ' + self.created_by.last_name)
I have tried:
days_requested = property(
lambda self: [(self.vacation_start + datetime.timedelta(days=i)).date()
for i in range(0, (self.vacation_end - self.vacation_start)) if (self.vacation_start + datetime.timedelta(days=i)).weekday() not in [5, 6].days()])
But I get the following error:
'datetime.timedelta' object cannot be interpreted as an integer
And as I perform operations with the amount of days asked I need to be able to get an integer.
Thank you all in advance.
UPDATE
class Model:
days_requested = models.IntegerField(blank=True,null=True)
def save(self, *args, **kwargs):
excluded = (6, 7)
days = 0
start_date =self.vacation_start
while start_date < self.vacation_end:
if start_date.isoweekday() not in excluded: #if you want to get only weekdays
days += 1
start_date+= timedelta(days=1)
self.days_requested=days
super(YourModel, self).save(*args, **kwargs)
After Elvin's answer I moved the hole logic to my view and set the logic inside form_valid function:
start = form.instance.vacation_start
end = form.instance.vacation_end
delta = end - start
excluded = (6, 7)
days = 0
for i in range(delta.days + 1):
day = start + datetime.timedelta(days=i)
if day.isoweekday() not in excluded:
days += 1
form.instance.days_requested = days
Thank you all.

How to store/create data with multiple dates for the same timetable

I have a model of a timetable as below:-
class time_table(models.Model):
username = models.ForeignKey(User,db_column="username", on_delete=models.CASCADE,)
sem_section = models.ForeignKey(sem_sections, db_column = "sem_section",on_delete=models.CASCADE,)
subject_id = models.ForeignKey(subjects,db_column="subject_id", on_delete=models.CASCADE,)
day_name = models.ForeignKey(days_ref, db_column = "days_ref",on_delete=models.CASCADE,)
hour_no = models.ForeignKey(hours, db_column = "hour_no",on_delete=models.CASCADE,)
def __str__(self):
ret = str(self.username) +' takes ' + str(self.sem_section) + " class " + str(self.subject_id) + " on " + str(self.hour_no) + " on " + str(self.day_name);
return ret
class Meta:
constraints = [
models.UniqueConstraint(fields=['sem_section', 'day_name', 'hour_no'], name='Allotment_check')
]
I have to create multiple records that repeat for each tuple that is inserted like if i insert a slot for monday 4th hour having some subject it must be created for multiple recurring dates of the whole year or semester.
Any sugestions on how to tweak the code or any extra code to add to achieve this goal.
I am using Postgres for database.
You can use Django's bulk_create along with (python) list comprehension to create multiple objects.

How to get currently selected choice from CharField in Django?

I'm trying to get the currently selected choice from the CharField and use it in str method like this:
class Foo(models.Model):
measurement_value = models.FloatField(max_length=200)
CHOICES = (('a', 'Alpha'), ('b', 'Beta'))
choice = models.CharField(max_length=5, choices=CHOICES, default='a')
def __str__(self):
"""String representation for the foo object."""
return str(self.measurement_value) + " " + self.choice
So for example, if I'd like to add object foo with measurement 10.5 and choice 'a' (Alpha), str would return this: "10.5 Alpha"
Currently, the code that I provided returns this: "10.5 a".
You can get the human readable choice name by using instance method get_{}_display
your example
def __str__(self):
return str(self.measurement_value) + " " + self.get_choices_display()

Django: Dynamic model field definition

Hi Stackoverflow people,
I have a model definition which is rather monotone, it includes fields for bins from 1 to 50.
For the proof of concept, I wrote it by hand, but there must be a better way to automate the model definition and to keep the code nice and tidy.
So far I did it the follow way:
class Bins(models.Model):
p1 = models.DecimalField(_('bin 1'), max_digits=6, decimal_places=2)
p2 = models.DecimalField(_('bin 2'), max_digits=6, decimal_places=2)
p3 = models.DecimalField(_('bin 3'), max_digits=6, decimal_places=2)
...
p50 = ...
On the Django wiki, I found a summary for dynamic model definitions, but its seems that it does not allow for loops in the definition:
I have tried the code below, but I get an error msg that MAX_BIN = 2 is an invalid syntax.
I understand the error that I can't iterated over the field like I tried.
Bins = type('Bins', (models.Model,), {
MAX_BIN = 50
for i in range(MAX_BIN):
name_sects = ["p", str(i)]
"".join(name_sects): model.DecimalField(_("".join([bin ', str(i)])),
max_digits=6, decimal_places=2)
})
Is such a dynamic class definition generally possible?
If so, what is the best way to define the class?
Thank you for your help!
in your current edition, your loop is inside the definition of a dict. that's not allowed. however, you could define your fields in a dict outside your call to type which works fine. something like
attrs = {
other_field = models.IntegerField(),
'__module__': 'myapp.models',
}
MAX_BIN = 50
for i in range(MAX_BIN):
name_sects = ["p", str(i)]
attrs["".join(name_sects)] = model.DecimalField(_("".join(['bin ', str(i)])),
max_digits=6, decimal_places=2)
Bins = type('Bins', (models.Model,), attrs)
A simple solution that solves the same issue:
class Bins(models.Model):
MAX_BIN = 50
for i in xrange(1, MAX_BIN + 1):
vars()['p' + str(i)] = models.DecimalField('bin ' + str(i),
max_digits=6, decimal_places=2)

Django model field relating to a few models

Imagine a 5x5 grid (map), every field of it represents a certain object (it can be a monster, a tree etc.)
So, here we have:
class Field(Model):
x = y = PositiveIntegerField()
content = ...(?)
Here the problem arises. Here is the alternative, but I think this way is too messy, especially if I have many different content ids.
class Field(Model):
x = y = PositiveIntegerField()
content = PositiveIntegerField()
monster_rel = ForeignKey(Monster, null=True, blank=True)
building_rel = ForeignKey(Monster, null=True, blank=True)
nature_obj_rel = ForeignKey(Monster, null=True, blank=True)
and then in a view:
f = Field.objects.get(pk=1)
if f.content == 1:
print "Monster %s of level %d" % (f.monster_rel.name, f.monster_rel.level)
elif f.content == 2:
print "This is a %s" % f.building_rel.type
...
Is there a better solution for this?
EDIT
I would like fields like:
content_id = IntegerField()
content_rel = FieldRelatedToModelByContentId()
Well, sounds like generic relations is exactly what you're looking for.