ModelChoiceField на внешнем ключе не работает - PullRequest
0 голосов
/ 15 мая 2019

У меня есть внешний ключ внутри модели, и я хочу настроить способ его отображения в форме.По умолчанию выбор появляется со значениями опции как id.Я хочу изменить значения параметра на другое поле.

Models.py:

class PriceDetails(models.Model):
    id = models.AutoField(primary_key=True)
    size = models.ForeignKey(SizeOd, blank=True, null=True, on_delete=models.DO_NOTHING)

    def __str__(self):
        return str(self.id)
class SizeOd(models.Model):
    size = models.DecimalField(unique=True, decimal_places=1, max_digits=5)
    multiplier = models.DecimalField(unique=True, decimal_places=3, max_digits=8)

    def __str__(self):
        return str(self.size)

Forms.py:

class PriceDetailsForm(forms.ModelForm):
    size = forms.ModelChoiceField(queryset=SizeOd.objects.order_by('size'), to_field_name="multiplier", required=False)
    class Meta:
        model = PriceDetails
        exclude = ('id',)

Views.py:

class PriceDetailsInline(InlineFormSetFactory):
    model = models.PriceDetails
    form = forms.PriceDetailsForm
    fields = '__all__'
    factory_kwargs = {'extra': 1, 'can_delete': False}

class CreateInvoiceView(LoginRequiredMixin, CreateWithInlinesView):
    model = models.Invoice
    form = forms.InvoiceForm
    inlines = [PriceDetailsInline]
    fields = '__all__'
    template_name = 'app/invoice_form.html'

Шаблон: invoice_form.html:

<form method="post">
    {% csrf_token %}
    {{form.as_p}}
    <div id="FormSet" class="my_inline">
        {% for formset in inlines %}
            <table id="FormSet{{ formset.prefix }}{{ forloop.counter }}">
                {{ formset.as_table }}
            </table>
            {{ formset.management_form }}

        {% endfor %}
    </div>
    <input type="submit" value="Create Invoice" >
</form>

<script type="text/javascript">
$(function() {
    {% for formset in inlines %}
        $('table#FormSet{{ formset.prefix }}{{ forloop.counter }}').formset();
    {% endfor %}
});
</script>

По умолчанию:

<select>
<option value='id1'>size1</option>
<option value='id2'>size2</option>
</select>

Ожидается:

<select>
<option value='*multiplier1*'>size1</option>
<option value='multiplier2'>size2</option>
</select>

РЕДАКТИРОВАТЬ: Мой вывод Значения параметров здесь - это идентификаторы, я хочу, чтобы они были мультипликаторами.ModelChoiceField не вносит никаких изменений.Поле выбора (поле размера) выглядит так же, если я исключаю 'size = forms.ModelChoiceField (queryset = SizeOd.objects.order_by (' size '), to_field_name = "multiplier", required = False)' в целом.Вместо этого следует отсортировать отображаемый текст в поле выбора по размеру и добавить множители в качестве значений.

Ответы [ 2 ]

0 голосов
/ 11 июня 2019

Нашел решение здесь .Проблема была не с ModelChoiceField.Ни одно из изменений, внесенных в forms.py, не было отражено в формах.(из-за использования InlineFormSetFactory) Перезаписал construct_inlines () (который является частью extra_views.advanced.ModelFormWithInlinesMixin) в views.py

class CreateInvoiceView(LoginRequiredMixin, CreateWithInlinesView):
model = models.Invoice
form = forms.InvoiceForm
inlines = [PriceDetailsInline]
fields = '__all__'
template_name = 'app/invoice_form.html'
def construct_inlines(self):
    inline_formsets = super(CreateInvoiceView, self).construct_inlines()
    inline_formsets[0].forms[0].fields['size'].queryset = models.SizeOd.objects.order_by('size')
    inline_formsets[0].forms[0].fields['size'].to_field_name = 'multiplier'
    return inline_formsets
0 голосов
/ 15 мая 2019

Вы можете настроить внешний вид модели в формах, изменив поле возврата

class PriceDetails(models.Model):
    ...

    def __str__(self):
        return str(self.size) # <--change this here from .id --> .size

Отредактировано

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...