I have two models defined in two different apps. I want to have a choice option for a particular field in a model, which is deriving those attributes from another field of a model in another app.
eg: I have a model "Inventory" that has a field 'title'.
class Inventory(models.Model):
title = models.CharField('Title', max_length=120, default='')
....
I also have another model 'Invoice' that has a field 'line_one'. Both these models are located in different apps.
class Invoice(models.Model):
line_one = models.CharField('Line 1', max_length=120)
....
I created a Django form for adding the Invoice details. I want a choice option for line_one that has all the values stored in the Inventory.title field so that the user can only select those values from a dropdown menu. How can I implement this? Thanks.
Edit: I referenced line_one to the field title of the Inventory model and it seems to work but it isn't exactly showing the name of the attributes but showing, "Inventory Object(7)", "Inventory Object(8)"
line_one = models.ForeignKey(Inventory, to_field='title', default=0, on_delete=models.CASCADE)
CodePudding user response:
Use a CharField
for line_one
class Inventory(models.Model):
title = models.CharField('Title', max_length=120, default='')
# ...
class Invoice(models.Model):
line_one = models.CharField('Line 1', max_length=120)
# ...
class InvoiceForm(forms.ModelForm):
line_one = forms.CharField(widget=forms.Select)
class Meta:
model = Invoice
fields = ['line_one', ] # ...
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# populate the choices from the Inventory model objects
self.fields['line_one'].widget.choices = [(i.title, i.title) for i in Inventory.objects.all()]
# or
self.fields['line_one'].widget.choices = [(t,t) for t in Inventory.objects.values_list('title', flat=True)
Use a ForeignKey
for line_one
If you like to use a ForeignKey
, it is necessary to have unique values for Inventory.title
.
class Inventory(models.Model):
title = models.CharField('Title', max_length=120, default='')
# ...
# The __str()__ method of an object is used by django
# to generate the labels for a Select input widget
def __str__(self):
return self.title
class Invoice(models.Model):
line_one = models.ForeignKey(Inventory, to_field='title', on_delete=models.CASCADE)
# ...
class InvoiceForm(forms.ModelForm):
class Meta:
model = Invoice
fields = ['line_one', ] # ...
# no need for any form adjustments,
# as django uses a select input as default for ForeignKey fields