Search code examples
djangodjango-modelsdjango-formsdjango-crispy-formsdjango-widget

Overriding ModelForm with widgets


A user has a form where he can save sensitive data. I am capable of crypting this data and store it in the database using modelforms. However, if the user wants to modify this data, it appears in the TextInput from the form.

I've read this post, and this one. The answer seems to be there, but I can't manage to suceed in the implementation. Here is what I have:

Models

class CustomUser(AbstractUser):
    api_key = models.CharField(max_length=256, default='null')

Forms

class APIForm(forms.ModelForm):
    class Meta:
        model = CustomUser
        fields = ('api_key')
        widgets = {
            'api_key': TextInput(attrs={'size': 10, 'placeholder': 'Your key'}),
        }

Html

  <form method="post">
    {% csrf_token %}
    {{ form|crispy }}
    <button type="submit">Save changes</button>
  </form>

It seems that the form is not detecting the widget, since if I change the value of the attribute size, the form will not change.

Am I missing something?

Thanks in advance

UPDATE.

Here is my view code simplified:

Views

class KeyView(LoginRequiredMixin, UpdateView):
    model = CustomUser
    form_class = APIForm
    template_name = 'account/api_form.html'
    success_url = reverse_lazy('pages:home')

    def get_object(self):
        return self.request.user

    def form_valid(self, form):
        self.object = form.save(commit=False)
        key=botcrypt.encrypt_val(self.object.api_key)
        self.object.api_key =key.decode("utf-8")
        self.object.save()
        messages.success(self.request, 'key updated with success!')
        return super().form_valid(form)

I'm using allauth for accounts, in case this information is important


Solution

  • So actually the solution was pretty simple, as expected....

    All the code from Models, Forms and html was right.

    I only had to empty the value of the key within the get_object from views:

    def get_object(self):
        self.request.user.api_key = ""
        return self.request.user