динамически заполненные поля в форме - PullRequest
3 голосов
/ 20 июня 2009

У меня есть две модели, которые выглядят так:

class RouteBase(models.Model):
    base        =   models.ForeignKey("Base")
    route       =   models.ForeignKey("Route")
    sequence    =   models.IntegerField()

class Route(models.Model):
    bases       =   models.ManyToManyField("Base", through="RouteBase", blank=True)
    description =   models.TextField(blank=True)
    #and a few other attributes omitted for brevity

... тогда модель выглядит следующим образом:

class RouteBaseForm(ModelForm):
    base = forms.ModelChoiceField(queryset=Base.objects.all(), widget=forms.TextInput)
    sequence = forms.IntegerField(widget=forms.HiddenInput)

    class Meta:
        model = RouteBase

Как видите, виджет последовательности скрыт, так как я хочу, чтобы это поле автоматически обрабатывалось django. Я хочу, чтобы пользователь просто вводил базу через текстовое поле. Последовательность определяется по порядку текстовых полей.

Я создал набор форм с этой формой для создания / редактирования всех баз в маршруте:

RouteBaseFormset = inlineformset_factory(Route, RouteBase, form=RouteBaseForm, extra=5, )

При создании этого набора форм поле последовательности будет пустым. Мне нужно заполнить его значениями, прежде чем я сохраню набор форм (иначе он не будет проверяться). Я могу придумать 4 способа сделать это

  1. Прямо перед отправкой формы в шаблон, я запускаю этот код:
    i=1
    for form in formset.forms:
        form.fields["sequence"].initial = i
        i += 1

Это отлично работает, за исключением одной проблемы. Когда набор форм возвращается в представление для сохранения, все 5 дополнительных полей, которые были созданы с помощью набора форм, заполняются значением последовательности. Это вызывает проблемы, когда пользователь хочет добавить 2 или 3 базы к маршруту. Всплывающие ошибки проверки, потому что для этой формы обязательное поле "база" пусто. Я мог бы запустить немного кода после того, как форма POST помещена, чтобы проверить, присутствует ли база, если нет, удалить последовательность, но если я собираюсь это сделать, я могу ...

  1. Выполните немного кода, когда набор форм POSTed проверяет, была ли введена база, если да, добавьте последовательность, если нет, то оставьте это поле пустым. Таким образом, при попытке .save() набора форм пустые значения гарантируют, что эта конкретная форма не будет помещена в базу данных. Единственная проблема заключается в том, что я ничего не могу сделать с формой, пока не введу .save(commit=False), что я не могу сделать, потому что форма не проверяется. Но я мог бы ...

  2. Добавьте значения последовательности, скопировав переменную request.POST и вручную установив последовательность, но это выглядит ужасно смешно.

  3. Я также мог бы просто удалить blank=True из одного из моих RouteBase полей, но я действительно не хочу этого делать.

Так что мне здесь делать?

Ответы [ 2 ]

5 голосов
/ 20 июня 2009

Если вы никогда не хотите, чтобы пользователь редактировал поле последовательности и планировал всегда вычислять его значение на внутреннем сервере, вы можете исключить его из формы , а не скрывать.

Затем вы можете использовать commit = False и обрабатывать вычисление поля последовательности по мере необходимости.

0 голосов
/ 21 июня 2009
newPOST = request.POST.copy()
i=1
for index in range(0, int(request.POST["routebase_set-TOTAL_FORMS"])-1):
    if request.POST["routebase_set-" + str(index) + "-base"]:
        newPOST["routebase_set-" + str(index) + "-sequence"] = i
        i += 1
    else:
        newPOST["routebase_set-" + str(index) + "-sequence"] = ""

Честно говоря, похоже, что это работает лучше, чем любая возня с проверкой формы. Это не так глупо, как я думал, что будет ...

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