I want to change the 'trans_recipient' field widget from being a dropdown, into being a text-input field. In the case of a large
I've tried the following :
class SafeTransactionForm(forms.ModelForm):
''' SafeTranSactionForm '''
trans_recipient = forms.CharField(widget=forms.TextInput(attrs={'class': 'special'}))
class Meta:
model = SafeTransaction
fields = [ 'trans_recipient',
'subject',
'arbitrator_name',
'payment_condition',
'amount_to_pay']
That produces this :
and although the widget itself has changed, actually trying to use it produces a value error as such :
without my incorrect one-line attempt at changing the widget :
class SafeTransactionForm(forms.ModelForm):
''' SafeTranSactionForm '''
class Meta:
model = SafeTransaction
fields = [ 'trans_recipient',
'subject',
'arbitrator_name',
'payment_condition',
'amount_to_pay']
the dropdown:
I've tried playing around with syntax, trying to update the widget within the meta class, I've mostly ended up with syntax errors and I've not been able to find examples of this specific case after some Google searches.
Insight and explanations are very much welcome and appreciated.
EDIT:
Now I am getting an error : ValueError: invalid literal for int() with base 10: 'inbox'
UpdateView class :
class SafeTransUpdateView(UpdateView):
'''
This view lets the user Update a SafeTransaction receipt
then send an automatic email to the email address
'''
form_class = SafeTransactionForm
model = SafeTransaction
template_name = "myInbox/safeTrans_update.html"
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(SafeTransUpdateView, self).__init__(*args, **kwargs)
def form_valid(self, form):
trans = form.save(commit=False)
trans.save()
### Send an email to the user upon transaction update.
usr_obj = User.objects.get(customuser=trans.trans_recipient)
user_mail = usr_obj.email
from_email = 'timi.ogunkeye@gmail.com'
contents = "This transaction [ " +trans.payment_condition+" ] has been updated !"
email_subject = 'Transaction Update !'
try:
send_mail(email_subject, contents, from_email, [user_mail], fail_silently=False)
pass
except:
pass
else:
pass
return HttpResponseRedirect('inbox')
my updated form :
class SafeTransactionForm(forms.ModelForm):
''' SafeTranSactionForm '''
# trans_recipient = forms.CharField(widget=forms.TextInput(attrs={'class':'special'}))
trans_recipient = forms.ModelChoiceField(queryset=CustomUser.objects.all(),
widget=forms.TextInput(attrs={'value':"username"}), to_field_name="username")
def clean_trans_recipient(self):
data = self.cleaned_data['trans_recipient']
try:
return CustomUser.objects.get(username=data)
except CustomUser.DoesNotExist:
raise forms.ValidationError("No user with this username exists")
class Meta:
model = SafeTransaction
fields = [ 'trans_recipient',
'trans_recipient_email',
'subject',
'arbitrator_name',
'payment_condition',
'amount_to_pay']
safeTrans_update.html :
<h1>TRANSACTION UPDATE: </h1>
<form action="{% url 'ST_update' object.pk %}" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Confirm Update" />
</form>
urls.py:
path('ST_update/<pk>',SafeTransUpdateView.as_view(),name='ST_update'),
I'd like to know why this error is now occuring : ValueError: invalid literal for int() with base 10: 'inbox' . Any info is very much appreciated.
Well the problem is that Django does not know how to convert the data from the form field back into a trans_recipient
attribute for the model (which should be a CustomUser
instance).
This is however not problematic: you can perform form cleaning, and thus write a custom function to transform the string back into a CustomUser
object, for example:
class SafeTransactionForm(forms.ModelForm):
''' SafeTranSactionForm '''
trans_recipient = forms.CharField(widget=forms.TextInput(attrs={'class': 'special'}))
def clean_trans_recipient(self):
data = self.cleaned_data['recipients']
try:
return CustomUser.objects.get(username=data)
except CustomerUser.DoesNotExist:
raise forms.ValidationError("No user with this username exists")
class Meta:
model = SafeTransaction
fields = [ 'trans_recipient', 'subject', 'arbitrator_name',
'payment_condition', 'amount_to_pay' ]
Although you will probably need to do some tweaking for the CustomUser
fetch. We thus aim to fetch such CustomUser
and return it. In case no such CustomUser
exists, then we raise a ValidationError
.