0

I am trying to combine Django's generic UpdateView and hidden input field. My purpose is to track whether a post was edited after it was created or not. Hidden field name is "updated".

views.py:

class PostUpdateView(UpdateView):
  model = Post
  template_name = 'journal/post_update_form.html'
  form_class = PostUpdateForm
  success_url = reverse_lazy('my_posts')

models.py:

class Post(models.Model):
  title = models.CharField(max_length=500)
  text = models.TextField(max_length=2000, null=True, blank=True)
  owner = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
  #storing the link to media files in CharField
  image = models.CharField(max_length=500, null=True, blank=True)
  audio = models.CharField(max_length=500, null=True, blank=True)
  video = models.CharField(max_length=500, null=True, blank=True)
  rubric = models.CharField(max_length=100, default="No rubric", choices=RUBRIC_CHOICES)
  private = models.BooleanField(default=False)
  created_at = models.DateTimeField(auto_now_add=True)
  updated_at = models.DateTimeField(auto_now=True)
  updated = models.CharField(max_length=10, default="False")

forms.py:

from django import forms
from .models import Post

class PostUpdateForm(forms.ModelForm):
  class Meta:
    model = Post
    fields = ["title", "text", "image", "audio", "video", "rubric", "private", "updated"]
    widgets = {'updated': forms.HiddenInput(attrs={'value':"updated"})}

relevant part of update form template:

 <form action="" method="POST">
        {% csrf_token %}

        {% for field in form %}
          {% if field != form.rubric and field != form.private %}
            <div class="mb-3 form-group">
              <label for="{{field.name}}" class="form-label">{{field.label}}</label>
                {{field.errors}}
                {% if field == form.text %}
                  <textarea type="text" class="form-control" id="{{field.name}}" name="{{field.name}}">{{field.value|default_if_none:"" }}</textarea>
                {% elif field == form.updated %}
                  <input type="hidden" id="{{field.name}}" name="{{field.name}}" value="updated">
                {% else %}
                  <input type="text" class="form-control" id="{{field.name}}" name="{{field.name}}" value="{{field.value|default_if_none:"" }}">
                {% endif %}
            </div>

           <...some other fields...>
            {% endif %}
        {% endfor %}

        <input type="submit" class="btn btn-primary" value="Update"/>
      </form>

Value of "updated" field is passed successfully, but the field value is visible (non-editable). In forms.py I tried to:

  • exclude 'updated' from fields list. Result: the value of "updated" is not saved.
  • use "widgets = {'updated': forms.HiddenInput}". Result: value is also passed successfully, but the field is still visible.
  • use only widgets in forms.py and comment out input field [1] in the template. Result: field is visible, editable, value is not saved.

[1] input field:

{% elif field == form.updated %}
                  <input type="hidden" id="{{field.name}}" name="{{field.name}}" value="updated">

I would appreciate any insights about what might be wrong here. Thank you in advance.

  • 1
    Check this: https://stackoverflow.com/a/60072461/10951070 – raphael Dec 29 '22 at 18:09
  • 1
    @raphael , thank you for taking a look! I've tried the accepted answer from that thead. It did not resolve my problem, but helped to notice where my mistake was. What I assumed to be a value of field displaying even when I try to hide it, turned out to be a just a field label :) For loop in my code was displaying labels for all fields. – cafelatte.here Dec 30 '22 at 17:07

1 Answers1

0

In PostUpdateForm you can do so:

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)

    self.fields['updated'].initial = 'updated'
    self.fields['updated'].disabled = True

https://docs.djangoproject.com/en/4.1/ref/forms/fields/#disabled

nznm
  • 26
  • 5
  • thank you for the suggestion! I tried it and got an error "'NoneType' object is not subscriptable". I tested with `print(self.fields)` and got "None". Also, I was able to understand where my mistake was. What I assumed to be a value of field displaying even when I try to hide it, turned out to be a just a field label :) For loop in my code was displaying labels for all fields. – cafelatte.here Dec 30 '22 at 17:15