Передача дополнительного поля формы из HTML для просмотра в Django - PullRequest
0 голосов
/ 18 мая 2018

Я следил за постом , когда я пытался найти решение, но оно не работает для меня.

Моя проблема:

У меня есть объект Django Model с 4 атрибутами.

Допустим, у меня есть что-то вроде этого

class MyModel(models.Model):
    user = models.ForeignKey('auth.User', on_delete=models.CASCADE)
    first_at = models.IntegerField()
    second_at = models.IntegerField()
    third = models.TextField()

Тогда у меня есть некоторыевид, в котором я хотел бы представить форму с этим объектом.Но я бы хотел, чтобы пользователь вставлял только 2 из них, user и параметр third необходимо заполнять автоматически;user от текущего пользователя и third от другого элемента HTML (в какой строке форма была заполнена).

class HomePage(LoginRequiredMixin, generic.CreateView):
    template_name = 'index.html'
    model = MyModel
    fields = ('first', 'second')
    success_url = reverse_lazy('home')

def form_valid(self, form):
    self.object = form.save(commit=False)
    self.object.user = self.request.user
    self.object.save()
    return super().form_valid(form)

Тогда я в HTML создал

    <form action="." method="POST">
        {% csrf_token %}
        {{ form.as_p }}
        <input type="hidden" name="third" value="{{ item.third }}" />
        <input type="submit" value="submit" />
    </form>

Кто-нибудьзнаете, почему это не работает?И или как мне заставить это работать?Есть ли лучший способ?

Марко

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Я нашел решение,

Проблема в том, что когда вы используете generic.CreateView и задаете либо поля, либо form_class, тогда этот класс будет читать только эти поля.Даже если вы добавите вручную дополнительное поле ввода, оно не будет передано внутри класса.

Чтобы решить эту проблему, я создал класс формы со скрытым полем.

class MyForm(forms.ModelForm):

    class Meta:
        model = models.OrderDetail
        fields = ('first', 'second', 'third')
        widgets = {
            'third' : forms.HiddenInput(),
        }

Затем я использую эту форму как обычный вид внутреннего класса

class HomePage(LoginRequiredMixin, generic.CreateView):
    template_name = 'index.html'
    model = MyModel
    form_class = forms.MyForm
    success_url = reverse_lazy('home')

Затем добавляем дополнительное скрытое поле внутри HTML-файла

<form action="." method="POST">
        {% csrf_token %}
        {{ form.as_p }}
        <input type="hidden" name="third" value="someValue" />
        <button type="submit" name="_submit" class="btn btn-raised btn-primary">Submit</button>
</form>

Таким образом, вы заменяетеваше скрытое поле, которое идет с form.as_p с пользовательским.

Примечание: Вы не на самом делезаменить поле.Если вы проверите код, то увидите, что у вас будет 2 скрытых поля, но только одно со значением.Но поскольку оба они скрыты, никто не может добавить ценность другому, поэтому поведение такое же, как и в случае замены поля.

0 голосов
/ 18 мая 2018

Вы можете попробовать этот подход

Создайте пользовательскую форму в файле forms.py и исключите поля, скажем

class UserForm(forms.ModelForm):
     class Meta:
          model=Mymodel
          exclude = ['user','third']

и в вашем представлении создания импортируйте созданную недавно форму и используйте ее в CreateView с form_clas

class HomePage(LoginRequiredMixin, generic.CreateView):
    form_class = UserForm
    template_name = 'index.html'
    model = MyModel
    fields = ('first', 'second')
    success_url = reverse_lazy('home')
...