Форма Джанго пропускает поле - PullRequest
0 голосов
/ 12 апреля 2011

У меня есть модель и модель формы, чтобы изменить некоторые настройки.Форма отображается правильно, с правильными значениями, но когда я отправляю форму, в запросе отсутствует одно поле. DOST dict.

Модель:

class NodeSettings(models.Model):
    nodetype = models.CharField(max_length=8, editable=False)
    nodeserial = models.IntegerField(editable=False)
    upper_limit = models.FloatField(null=True, blank=True,
                                    help_text="Values above this limit will be of different color.")
    graph_time = models.IntegerField(null=True, blank=True,
                                     help_text="The `width' of the graph, in minutes.")
    tick_time = models.IntegerField(null=True, blank=True,
                                    help_text="Number of minutes between `ticks' in the graph.")
    graph_height = models.IntegerField(null=True, blank=True,
                                       help_text="The top value of the graphs Y-axis.")

    class Meta:
        unique_together = ("nodetype", "nodeserial")

Класс представления (Я использую Django 1.3 с представлениями на основе классов):

class EditNodeView(TemplateView):
    template_name = 'live/editnode.html'

    class NodeSettingsForm(forms.ModelForm):
        class Meta:
            model = NodeSettings

    # Some stuff cut out

    def post(self, request, *args, **kwargs):
        nodetype = request.POST['nodetype']
        nodeserial = request.POST['nodeserial']

        # 'logger' is a Django logger instance defined in the settings
        logger.debug('nodetype   = %r' % nodetype)
        logger.debug('nodeserial = %r' % nodeserial)

        try:
            instance = NodeSettings.objects.get(nodetype=nodetype, nodeserial=nodeserial)
            logger.debug('have existing instance')
        except NodeSettings.DoesNotExist:
            instance = NodeSettings(nodetype=nodetype, nodeserial=nodeserial)
            logger.debug('creating new instance')

        logger.debug('instance.tick_time = %r' % instance.tick_time)

        try:
            logger.debug('POST[tick_time] = %r' % request.POST['tick_time'])
        except Exception, e:
            logger.debug('error: %r' % e)

        form = EditNodeView.NodeSettingsForm(request.POST, instance=instance)
        if form.is_valid():
            from django.http import HttpResponse
            form.save()
            return HttpResponse()
        else:
            return super(EditNodeView, self).get(request, *args, **kwargs)

Соответствующая часть шаблона:

<form action="{{ url }}edit_node/" method="POST">
  {% csrf_token %}
  <table>
    {{ form.as_table }}
  </table>
  <input type="submit" value="Ok" />
</form>

Вот вывод отладки в консоли при запуске отладкисервер:

2011-04-12 16:18:05,972 DEBUG nodetype   = u'V10'
2011-04-12 16:18:05,972 DEBUG nodeserial = u'4711'
2011-04-12 16:18:06,038 DEBUG have existing instance
2011-04-12 16:18:06,038 DEBUG instance.tick_time = 5
2011-04-12 16:18:06,039 DEBUG error: MultiValueDictKeyError("Key 'tick_time' not found in <QueryDict: {u'nodetype': [u'V10'], u'graph_time': [u'5'], u'upper_limit': [u''], u'nodeserial': [u'4711'], u'csrfmiddlewaretoken': [u'fb11c9660ed5f51bcf0fa39f71e01c92'], u'graph_height': [u'25']}>",)

Как видите, поле tick_time отсутствует в QueryDict из request.POST.

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

У кого-нибудь есть намеки на то, что может быть не так?

1 Ответ

1 голос
/ 12 апреля 2011

Поскольку вы используете общий вид, не лучше ли расширить ProcessFormView вместо TemplateView?

РЕДАКТИРОВАТЬ

Iпробовал ваш код с TemplateView:

class EditNodeView(TemplateView):

У вас есть get_context_data, чтобы нажать форму?

def get_context_data(self, **kwargs):
    instance = NodeSettings.objects.get(pk=kwargs['node_id'])
    form = EditNodeView.NodeSettingsForm(instance=instance)
    context = super(EditNodeView, self).get_context_data(**kwargs)
    context['form'] = form
    return context

Лучший способ редактирования существующих объектов - это получитьпо первичному ключу у меня есть следующее в urls.py:

url(r'^edit-node/(?P<node_id>\d+)/$', EditNodeView.as_view(), name='edit-node'),

Я извлекаю экземпляр по первичному ключу, возможно, потребуется выполнить некоторую проверку выше, например, выбрав 404, если ее нет.* В ваших моделях у вас есть nodetype и nodeserial как editable=False, как вы отображаете или создаете эти элементы, если они не доступны для редактирования?Я установил их на True для целей тестирования.

В шаблоне я изменил первую строку на:

<form action="" method="POST">

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

...