This is a follow up question to this question:
How to pass user object to forms in Django
Here is my form:
class SellForm(forms.Form):
symbol = forms.ModelChoiceField(queryset=None, widget=forms.Select(attrs={
'class': 'form-control',
'placeholder': 'Symbol',
'autofocus': 'autofocus',
}))
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super(SellForm, self).__init__(*args, **kwargs)
self.fields['symbol'].queryset = Holdings.objects.filter(student=self.request.user.student)
This form is providing me with this dropdown:
I have extra information in the model which is the purchase price of each share, is there a way to get this onto the form also? It would have to be non editable though as its the price that the share was purchased at.
Here is the model that the form is getting the data from:
class Holdings(models.Model):
student = models.ForeignKey(Student, on_delete=models.CASCADE)
symbol = models.CharField(max_length=10)
purchase_price = models.DecimalField(max_digits=10, decimal_places=2)
class Meta:
verbose_name_plural = "Holdings"
ordering = ['symbol']
def __str__(self):
return self.symbol
I would very much appreciate any help if possible! Thank you!
3
Answers
I have managed to get it to work with some help from copilot.
it is one extra line of code so the form now looks like this:
Its a pretty hideous and long lambda function that I don't really understand, but I figured out how to access the purchase price from the view and then just tacked that part (the .values_list...) on to the lambda function and it worked. Below is what I've managed, which is pretty much what I wanted.
Thanks for taking a look and helping, hopefully this helps some others that may be stuck on this too!
The simplest way is just overriding the
__str__
method and include the purchase price:Filtering can be done more efficiently though with:
since this will prevent a query to get the
Student
object for the user, or we can work with:You can add an extra field to a modelForm and make it uneditable.
A more elegant way, in my opinion, is to include the data in the context that’s sent to the form , and render that field alone separately in the form’s template.html page. i.e. send purchase_history as part of the context data to the view that renders the form .
Check the answers here:
In a Django form, how do I make a field readonly (or disabled) so that it cannot be edited?
Django add extra field to a ModelForm generated from a Model
https://docs.djangoproject.com/en/4.2/ref/forms/fields/#disabled