Populate combos in Django and initialize them with a foreign key - django

I need to populate two combos in a ModelForm, and I would like to initialize them with the current value of each foreign key.
My models are:
class Alumno(models.Model):
idalumno = models.AutoField(primary_key=True)
padre_idpadre = models.ForeignKey('Padre', models.DO_NOTHING, db_column='padre_idpadre', blank=True, null=True)
curso_idcurso = models.ForeignKey('Curso', models.DO_NOTHING, db_column='curso_idcurso')
nombre = models.CharField(max_length=45, blank=True, null=True)
class Meta:
db_table = 'alumno'
class Curso(models.Model):
idcurso = models.IntegerField(primary_key=True)
nombrecurso = models.CharField(max_length=45, blank=True, null=True)
class Meta:
db_table = 'curso'
class Padre(models.Model):
idpadre = models.AutoField(primary_key=True)
socio = models.NullBooleanField(blank=True, null=True)
nombre = models.CharField(max_length=45, blank=True, null=True)
primerapellido = models.CharField(max_length=45, blank=True, null=True)
segundoapellido = models.CharField(max_length=45, blank=True, null=True)
class Meta:
db_table = 'padre'
This is my Form in forms.py:
class AlumnoForm(forms.ModelForm):
padre = PadreModelChoiceField(queryset=Padre.objects.all(), initial=**XXXXXXXXX**) #I would like to init here with the value of the FK
curso = CursoModelChoiceField(queryset=Curso.objects.all(), initial=**XXXXXXXXXX**) #And here too
class Meta:
model = Alumno
fields = ('nombre','padre','curso',)
labels = {
'nombre': 'Nombre',
'padre': 'Padre',
'curso': 'Curso',
}
In views.py
def alumno_editar(request, pk):
alumno = get_object_or_404(Alumno, pk=pk)
if request.method == "POST":
form = AlumnoForm(request.POST, instance=alumno)
if form.is_valid():
alumno = form.save(commit=False)
alumno.save()
return redirect('alumno_listar')
else:
form = AlumnoForm(instance=alumno)
return render(request, 'administration/alumno_editar.html', {'form': form})
What should I write in the part XXXXXXXXXX of the code.
It could be misconception but I'm think is a common operation, althought I don't find it.

Related

Django duplicate key when trying to send a form with foreign key

I need to save a form with listaflor and multiple instances of flora2estado,When i try to send this form i get:
IntegrityError at /enviar_flora/
(1062, "Duplicate entry '99-10031' for key 'PRIMARY'")
views.py:
def CreateFlo(request):
form = FloForm()
if request.method == 'POST':
form = FloForm(request.POST)
if form.is_valid():
listafor = form.save()
estados = form.cleaned_data.get('estados')
for estado in estados:
Flora2Estado.objects.create(especie=listafor, estado= estado)
# or you can use bulk_create: https://docs.djangoproject.com/en/3.0/ref/models/querysets/#bulk-create
return render(request,'accounts/enviar_flora.html')
models.py:
class Listaflor(models.Model):
especie_id = models.AutoField(db_column="especie_id",primary_key=True)
familia = models.ForeignKey(Familia, models.DO_NOTHING, db_column='familia_id', blank=True, null=True)
Especie = models.CharField(db_column='especie', max_length=255, blank=True, null=True)
class Meta:
managed = True
db_table = 'listaflor'
class Flora2Estado(models.Model):
estado = models.ForeignKey(EstadosM, models.CASCADE)
especie = models.ForeignKey(Listaflor, models.CASCADE,default=99999)
flora2estado = models.AutoField(primary_key=True, default=99999)
class Meta:
managed = True
db_table = 'flora2estado'
unique_together = (('estado', 'especie'),)
class EstadosM(models.Model):
estado_id = models.AutoField(primary_key=True)
estado_nome = models.CharField(max_length=100, blank=True, null=True)
nome_abbr = models.CharField(max_length=2, blank=True, null=True)
criadoem = models.DateTimeField(db_column='criadoEm')
class Meta:
managed = False
db_table = 'estados'
def __str__(self):
return self.estado_nome

django - How can I prefill formset forms data using database query result?

I am creating a student attendance form where need to get details of student name, student class and Id from student model based on teacher selecting student class in one form. I have tried using initial by using for loop on query data to prefill the form in formset, however it populates data for one record only. Below is the code for forms.py, models and views.py. Can someone help on this
forms.py
class student(models.Model):
studentid = models.AutoField(primary_key=True)
Gender = models.CharField(max_length=6, choices=gender, null=True)
Name = models.CharField(max_length=100, null=True)
DOB = models.DateField(null=True)
Image = models.ImageField(null=True, upload_to='images')
Status = models.CharField(max_length=10, choices=statchoice, null=True)
Father_name = models.CharField(max_length=100, null=True)
Mother_name = models.CharField(max_length=100, null=True)
Address = models.CharField(max_length=200, null=True)
Contact_no = models.IntegerField(null=True)
Email = models.EmailField(null=True)
Admission_class = models.CharField(max_length=40, null=True, choices=grade)
Admission_date = models.DateField(null=True)
Current_class = models.CharField(max_length=40, null=True, choices=grade)
Leaving_date = models.DateField(null=True, blank=True)
objects = models.Manager()
def __str__(self):
return str(self.studentid)
class student_attendance(models.Model):
Student_ID = models.CharField(max_length=100, null=True)
Student_Name = models.CharField(max_length=100, null=True)
Student_class = models.CharField(max_length=100, null=True, choices=grade)
Attendance_date = models.DateField(null=True, auto_now_add=True, blank=True)
Attendance_status = models.CharField(choices=attendance, null=True, max_length=10)
objects = models.Manager()
Views.py
def student_attend(request):
if request.method == 'POST':
data = request.POST.get('studentGrade')
formset_data = student.objects.filter(Current_class=data)
AttendanceFormSet = formset_factory(std_attendance, extra=(len(formset_data))-1)
for element in formset_data:
formset = AttendanceFormSet(initial=[
{'Student_ID': element.studentid, 'Student_Name':element.Name, 'Student_class':element.Current_class, 'Attendance_status':"Present"}
])
param = {'formset':formset}
return render(request, 'home/student_attendance.html', param)
return render(request, 'home/student_attendance.html')
form.py:
class student_register(ModelForm):
class Meta:
model = student
fields = '__all__'
class std_attendance(ModelForm):
class Meta:
model = student_attendance
fields = '__all__'
Each iteration in your loop you override the formset, that is why only a single form is filled, you need to fill the param with all the forms inside the loop this way:
initial = []
for element in formset_data:
initial.append({'Student_ID': element.studentid, 'Student_Name':element.Name, 'Student_class':element.Current_class, 'Attendance_status':"Present"}
formset = AttendanceFormSet(initial=initial)

Django: how to define form in class based views? -> error Cannot assign '..' '..' must be a "Utilisateur" instance

I have already posted (see link below) to 'valid' my ER diagram.
I try to develop a form based on 'trought' model with nested inlineformset.
It works when I define fields in the UtilisateurCreateView class but I want to customize the 'trought' parent's form to be able to:
set initial pro_ide value with value send by GET
hidden this pro_ide field
customize uti_ide field label
So I define a UtilisateurProjetCreateForm based on the 'throught' model like I'm used to do but I got an error:
Cannot assign "'Slater, Kelly (k.slater#surf.com)'": "UtilisateurProjet.uti_ide" must be a "Utilisateur" instance.
moreover, as this form is based on 'throught' model, I am not sure I should define forms.ChoiceField...
models.py
class Projet(SafeDeleteModel):
_safedelete_policy = SOFT_DELETE_CASCADE
pro_ide = models.AutoField(primary_key = True)
# utilisateurs = models.ManyToManyField(Utilisateur, through='UtilisateurProjet')
pro_nom = models.IntegerField("Nom du projet")
pro_log = models.CharField("Log utiisateur", max_length=20, null=True, blank=True)
pro_dat = models.DateTimeField("Date log",auto_now_add=True)
pro_act = models.IntegerField("Projet en cours ?", null=True, blank=True)
class Meta:
db_table = 'tbl_pro'
verbose_name_plural = 'Projets'
ordering = ['pro_ide']
permissions = [
('can_add_project','Can add project'),
]
def __str__(self):
return f"{self.pro_nom}"
class Utilisateur(SafeDeleteModel):
_safedelete_policy = SOFT_DELETE_CASCADE
uti_ide = models.AutoField(primary_key = True)
# pro_ide = models.ForeignKey(Projet, on_delete = models.CASCADE) # related project
projets = models.ManyToManyField(Projet, through='UtilisateurProjet')
uti_nom = models.CharField("Nom", max_length=20)
uti_pre = models.CharField("Prénom", max_length=20)
uti_mai = models.CharField("Email", max_length=40)
uti_sit = models.CharField("Equipe", max_length=20, null=True, blank=True)
uti_pro = models.CharField("Fonction/profil", max_length=200, null=True, blank=True)
uti_dem_dat = models.DateTimeField("Date demande",auto_now_add=True, null=True, blank=True)
uti_val = models.IntegerField("Demande validée ?", null=True, blank=True)
uti_val_dat = models.DateTimeField("Date validation",null=True, blank=True)
uti_log = models.CharField("Log utilisateur", max_length=20, null=True, blank=True)
uti_dat = models.DateTimeField("Date log",auto_now_add=True, null=True, blank=True)
class Meta:
db_table = 'tbl_uti'
verbose_name_plural = 'Utilisateurs'
ordering = ['uti_ide']
def __str__(self):
return f"{self.uti_nom}, {self.uti_pre} ({self.uti_mai})"
class UtilisateurProjet(models.Model):
_safedelete_policy = SOFT_DELETE_CASCADE
pro_uti_ide = models.AutoField(primary_key = True)
uti_ide = models.ForeignKey(Utilisateur, on_delete=models.CASCADE)
pro_ide = models.ForeignKey(Projet, on_delete=models.CASCADE)
class Meta:
db_table = 'tbl_pro_uti'
class Application(SafeDeleteModel):
_safedelete_policy = SOFT_DELETE_CASCADE
app_ide = models.AutoField(primary_key = True)
# uti_ide = models.ForeignKey(Utilisateur, on_delete = models.CASCADE) # related utilisateur
pro_uti_ide = models.ForeignKey(UtilisateurProjet, on_delete = models.CASCADE) # related utilisateur-projet
app_app_nom = models.IntegerField("Nom application", null=True, blank=True)
app_dro = models.IntegerField("Droit sur application", null=True, blank=True)
app_sta = models.IntegerField("Statut (création/Modification/Suppression", null=True, blank=True)
app_log = models.CharField("Log utilisateur", max_length=20, null=True, blank=True)
app_dat = models.DateTimeField("Date log",auto_now_add=True, null=True, blank=True)
class Meta:
db_table = 'tbl_app'
verbose_name_plural = 'Applications'
ordering = ['app_ide']
views.py
# https://stackoverflow.com/questions/29981690/django-form-validation-on-class-based-view
class UtilisateurCreateView(FormView):
template_name = 'project/utilisateurprojet_form.html'
form_class = UtilisateurProjetCreateForm
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
if self.request.POST:
data["utilisateur"] = self.request.user.username # nom de l'utilisateur connecté
data["projet"] = get_object_or_404(Projet, pro_ide = self.request.GET['projet'])
data["application"] = ApplicationFormset(self.request.POST)
else:
data["application"] = ApplicationFormset()
return data
def form_valid(self, form):
context = self.get_context_data()
application = context["application"]
self.object = form.save(commit=False)
self.object.uti_log = context["utilisateur"]
self.object.save()
if application.is_valid():
application.instance = self.object
application.save()
return super().form_valid(form)
def get_success_url(self):
return reverse("project:index")
forms.py
ApplicationFormset = inlineformset_factory(
UtilisateurProjet, Application,
fields=('app_app_nom','app_dro'),
widgets={
'app_app_nom': forms.Select(choices=NAME),
'app_dro': forms.Select(choices=ACCESS)
},
extra=3,
can_delete=True,
)
class UtilisateurProjetCreateForm(forms.ModelForm):
PROJETS = [(Projet.objects.get(pro_ide=1),'Coverage Africa'),]
UTILISATEURS = [(Utilisateur.objects.get(uti_ide=1),'Slater'),]
pro_ide = forms.ChoiceField(label = "Nom projet", widget = forms.Select, choices = PROJETS, initial = Projet.objects.get(pro_ide=1), disabled=True)
uti_ide = forms.ChoiceField(label = "Nom, prénom de l'utilisateur", widget = forms.Select, choices = UTILISATEURS)
class Meta:
model = UtilisateurProjet
fields = ('pro_ide','uti_ide')
related post
I had to use ModelChoiceFiled in my ModelForm:
class UtilisateurProjetCreateForm(forms.ModelForm):
PROJETS = Projet.objects.all()
UTILISATEURS = Utilisateur.objects.all()
pro_ide = forms.ModelChoiceField(queryset = PROJETS, label = "Nom projet", widget = forms.Select, initial = Projet.objects.get(pro_ide=1))
uti_ide = forms.ModelChoiceField(queryset = UTILISATEURS, label = "Nom, prénom de l'utilisateur", widget = forms.Select)
class Meta:
model = UtilisateurProjet
fields = ('pro_ide','uti_ide')

Query django foreignkey relationship

I am developing an audit management information system where I can record all finding related to an audit. I have models with foreignkeys relationship. How do I see all findings with a particular assignment and audit_title and unit?
See relevant codes below.
model.py content
class Unit(models.Model):
unit_name = models.CharField(max_length=30, blank=True, null=True)
def __unicode__(self):
return self.unit_name
class Assignment(models.Model):
assignment_name = models.CharField(max_length=30, blank=True, null=True)
def __unicode__(self):
return self.assignment_name
class Task(models.Model):
task_title = models.CharField(max_length=35, blank=True, null=True)
return self.task_title
class Finding(models.Model):
assignment = models.ForeignKey(Assignment, blank=True, null=True)
audit_title = models.ForeignKey(Task, blank=True, null=True)
auditor = models.ManyToManyField(User, blank=True)
unit = models.ForeignKey(Unit, blank=True, null=True)
audit_period = models.DateField(auto_now_add=False, auto_now=False, blank=True, null=True)
contact_person = models.CharField('Contact Person', max_length=500, blank=True, null=True)
finding = models.TextField('Detail Finding', max_length=500, blank=True, null=True)
be = models.CharField(max_length=30, blank=True, null=True)
form.py
class FindingSearchForm(forms.ModelForm):
class Meta:
model = Finding
fields = ['assignment',
'audit_title',
'unit',
'be',
]
Am I have the following in my views.py but I have this error invalid literal for int() with base 10: ''
views.py content
def finding_list(request):
title = 'List of Finding'
queryset = Finding.objects.all()
queryset_count = queryset.count()
form = FindingSearchForm(request.POST or None)
context = {
"title": title,
"form": form,
"queryset_count": queryset_count,
}
if request.method == 'POST':
unit = form['unit'].value()
audit_title = form['audit_title'].value()
assignment = form['assignment'].value()
queryset = Finding.objects.all().order_by('-timestamp').filter(be__icontains=form['be'].value(),
unit_id=unit,
assignment_id=assignment,
audit_title_id=audit_title,)
if request.method == 'POST':
unit = form['unit'].value()
audit_title = form['audit_title'].value()
assignment = form['assignment'].value()
queryset = Finding.objects.all().order_by('-timestamp').filter(be__icontains=form['be'].value()
)
if (unit != ''):
queryset = queryset.filter(unit_id=unit)
if (audit_title != ''):
queryset = queryset.filter(audit_title_id=audit_title)
if (assignment != ''):
queryset = queryset.filter(assignment_id=assignment)

How do I make sure entered integer is greater than current value before updating model field?

I am using a form that saves to one model to update the most current mileage which is stored in another model. I want to make sure the mileage entered is > or = the current mileage. I havent been able to figure out the right validation or where to write the validation.
I have tried an if statement in the form_valid() of the CreateView and a save() method in the model.
Models.py
class Vehicle(models.Model):
name = models.CharField(blank=True, max_length=100)
make = models.CharField(blank=True, max_length=100)
model = models.CharField(blank=True, max_length=100)
year = models.IntegerField(blank=True, null=True)
vin = models.CharField(blank=True, max_length=17)
gvw = models.IntegerField(blank=True, null=True)
license_plate = models.CharField(blank=True, max_length=100)
purchase_date = models.DateField()
current_mileage = models.IntegerField(blank=True, null=True)
class Meta:
ordering = ['name']
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('vehicles:vehicle_detail', kwargs={'pk':self.pk})
#property
def get_current_mileage(self):
return self.current_mileage
class FuelEntry(models.Model):
vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
fuel_choices = (
('EMPTY', 'Empty'),
('1/8', '1/8'),
('1/4', '1/4'),
('1/2', '1/2'),
('3/4', '3/4'),
('FULL', 'Full'),
)
current = models.CharField(max_length=5, choices=fuel_choices)
after = models.CharField(max_length=5, choices=fuel_choices, blank=True)
gallons = models.DecimalField(decimal_places=2, max_digits=5, blank=True, default='0')
cost = models.DecimalField(decimal_places=2, max_digits=5, blank=True, default='0')
mileage = models.IntegerField(blank=False)
user = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
ordering = ['-date', 'vehicle']
def __str__(self):
return self.vehicle.name
def get_absolute_url(self):
return reverse('fuellog:entry_detail', kwargs={'pk':self.pk})
Views.py
class CreateEntry(CreateView):
model = FuelEntry
fields = ('vehicle', 'current', 'after', 'gallons', 'cost', 'mileage')
def form_valid(self,form):
self.object = form.save(commit=False)
self.object.user = self.request.user
vehicle_id = self.object.vehicle.pk
mileage = self.object.mileage
self.object.save()
current_mileage = Vehicle.objects.filter(id=vehicle_id).get('current_mileage')
if current_mileage > mileage:
raise ValidationError('Incorrect mileage reading')
Vehicle.objects.filter(id=vehicle_id).update(current_mileage=mileage)
return super().form_valid(form)
ValueError at /fuel/new
too many values to unpack (expected 2)