Я боролся с этой проблемой весь день и надеюсь, что кто-нибудь может помочь.Все мои иерархии классифицированы по категориям в одной таблице.во время создания формы я хочу разделить каждую иерархию по категориям и отобразить ее с помощью ModelMutipleChoiceField, чтобы не все иерархии отображались вместе.
Проблема возникает при отправке формы, так как мне нужно пройти через каждуюПоле ModelMutipleChoiceField и получите выбранные значения и скопируйте их в поле модели перед сохранением формы.Тем не менее, я не могу перебрать ModelMutipleChoiceField и получить выбранные значения.Я также не знаю, как установить эти значения в ModelField
ПРИМЕЧАНИЕ: Количество иерархий может варьироваться.
вот мой код:
Я использую Django MPTT и создаю свою иерархическую структуру, используя 2 модели.одна - это категория (Hierarchy), а другая - узлы иерархии (HierarchyNode_MPTT).
Затем я создал отдельную модель, в которой ManyToManyField указывает на HierarchyNode_MPTT.
Модели.py
class Hierarchy(models.Model):
ID = kp.ObjectIDField()
name = kp.ObjectNameField()
ext_hierarchy = kp.ObjectTechnicalID()
seq_no = kp.SeqNoField(unique=True)
mptt_seq_no = models.PositiveIntegerField()
class HierarchyNode_MPTT(MPTTModel):
id = kp.ObjectIDField()
name = kp.ObjectNameField()
description = kp.ObjectDescriptionField()
ext_node_id = kp.ObjectShortNameField()
parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
hierarchy = models.ForeignKey(Hierarchy, on_delete=models.CASCADE, null=True, blank=True, related_name='children')
class Configuration(models.Model):
uuid = kp.ObjectIDField()
name = kp.ObjectNameField()
description = kp.ObjectDescriptionField()
hierarchy_nodes = models.ManyToManyField(HierarchyNode_MPTT)
Затем я создал форму и реализовал метод init , чтобы автоматически создавать столько иерархий, сколько мне нужно. Форма
.py
class ConfigurationCreateForm(forms.ModelForm):
class Meta:
model = ForecastConfiguration
exclude = ['uuid', 'hierarchy_nodes']
def __init__(self, user, *args, **kwargs):
super().__init__(*args, **kwargs)
hierarchies = Hierarchy.objects.all()
for hierarchy in hierarchies:
field_name = 'hierarchy_%s' % (hierarchy.mptt_seq_no,)
self.fields[field_name] = TreeNodeMultipleChoiceField(queryset=HierarchyNode_MPTT.objects.all().filter(hierarchy=hierarchy),label=hierarchy.name, required=True)
try:
self.initial[field_name] = HierarchyNode_MPTT.objects.root_node(tree_id=hierarchy.mptt_seq_no)
except IndexError:
self.initial[field_name] = ''
def copy_hierarchies(self, *args, **kwargs):
hierarchies = Hierarchy.objects.all()
choice_list = list()
for hierarchy in hierarchies:
field_name = 'hierarchy_%s' % (hierarchy.mptt_seq_no,)
selected_values = self.cleaned_data.get(field_name)
for selection in selected_values:
choice_list.append(selection)
self.initial['hierarchy_nodes'] = choice_list
Наконец, идея заключалась в том, чтобы реализовать метод post в представлении для циклического создания созданных иерархий, а затем присвоить значение полю модели, называемому «ierarchy_nodes »
view.py
class ConfigurationCreateView(CreateView):
model = Configuration
form_class = ConfigurationCreateForm
template_name = 'frontend/base/config_create.html'
def get(self, request, *args, **kwargs):
form = ConfigurationCreateForm(user=request.user)
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
form.copy_hierarchies(*args, **kwargs)
if form.is_valid():
fcc_form = form.save(commit=True)
messages.add_message(self.request, messages.INFO, 'Your Forecast Configurations has been saved')
return redirect(reverse('planning_detail', kwargs={'uuid': self.fcc_form.uuid}))
else:
messages.add_message(self.request, messages.ERROR, 'Error when creating the Forecast Configuration')
return render(request, self.template_name, {'form': form})
Как вы можете видеть, я создал в своей форме метод с именем copy_hierarchies, в который я планировал копировать значения иерархии, это метод, в которомУ меня проблемы.
Если есть более простой способ сделать это с помощью Javascript, я открыт для этих опций.
Заранее спасибо.