Django динамически добавляет целочисленные поля в формы
Здравствуйте, у меня есть очень простое приложение, которое я делаю для того, чтобы изучить Django.
У меня есть таблица SQLite, в которой есть два столбца, первый - 'id
', сгенерированный Django, второй - символьное поле, содержащее имя product_name
.
Я пытаюсь заставить программу работать следующим образом:
- Получение списка значений в таблице. Этот набор_запросов присваивается
bases
- Пройдитесь по каждому кортежу в списке
bases
и используйте эти значения для создания полей формы. Таким образом,product_name
будет Label, аid
- id поля. Позже я буду использовать Jquery для этих полей, чтобы получить значения.
У меня есть следующий код:
from django import forms
from django.db import models
from django.core.exceptions import ValidationError
from .models import Department, Test_list, Products, Current_tests
class Batch(forms.Form):
bases = Products.objects.all().values_list('product_name','id')
for i in bases:
for j in [0,1]:
bn = i[0]
bnid = i[1]
name = forms.IntegerField(label=f"{bn}",widget=forms.NumberInput(attrs={"id":bnid}))
Код действительно работает, но вместо того, чтобы получить количество текстовых вводов, равное количеству строк в моей базе данных, он показывает только последнюю строку. Я полагаю, что это происходит потому, что в цикле я просто переназначаю другое значение "name"
. Сам цикл работает, и если я выведу i[0], он выведет все записи в столбце. Это связано с тем, как я добавляю поле в форму.
Любая помощь в решении этой небольшой проблемы будет очень признательна.
Вы можете сделать это в методе __init__
вашей формы.
class Batch(forms.Form):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
bases = Products.objects.all().values_list('product_name', 'id')
for product_name, product_id in bases:
self.fields[str(product_id)] = forms.IntegerField(
label=product_name,
widget=forms.NumberInput(attrs={"id": product_id})
)
Это создаст поле для каждого товара в базе данных. Каждое поле добавляется в форму на основе цикла, поэтому вы можете создать столько полей ввода, сколько строк в вашей базе данных.
Есть два способа. Наиболее правильным, на мой взгляд, будет работать с formsets
, таким образом, вы сможете легко изменять и сохранять несколько объектов:
views.py
def batch(request):
qs = Products.objects.all()
ProductsFormSet = formset_factory(Batch, extra=0)
initial = [{"id": obj.id, "product_name": obj.product_name} for obj in qs]
formset = ProductsFormSet(initial=initial)
return render(request, "batch.html", {"formset": formset})
forms.py
class Batch(forms.Form):
name = forms.IntegerField()
def __init__(self, *args, **kwargs):
super(Batch, self).__init__(*args, **kwargs)
self.fields["name"].label = self.initial["product_name"]
self.fields["name"].initial = self.initial["id"]
Второй вариант
Для динамического создания полей в одной форме, как вы хотите:
views.py
def batch(request):
qs = Products.objects.all()
form = AlternativeBatch(queryset=qs)
return render(request, "batch.html", {"form": form})
forms.py
class Batch(forms.Form):
def __init__(self, queryset, *args, **kwargs):
super(Batch, self).__init__(*args, **kwargs)
for product in queryset:
self.fields[str(product.id)] = forms.IntegerField(
label=product.product_name, initial=product.id
)