Reputation: 308
I have a simple model (kit) connected by another model(client_id) with a foreign key, and also by a ManyToMany
field. I have a form view for the kit model, in which user can create new kits, by selecting a few products, and then choosing which client it is made for. Problem is, the fields are being displayed correctly, but with only ID displayed, instead of their names. User does not know what is he selecting as he does not know the ID of all products or clients. How should I approach this ? I searched on SO but found nothing useful.
models.py
# Parent model connected with both models
class Kit(models.Model):
kit_name = models.CharField(max_length=255, default=0)
kit_info = models.CharField(max_length=255, default=0)
components_per_kit = models.IntegerField(default=0)
product_id = models.ManyToManyField(Product, related_name='kit_product')
quantity_per_kit = models.IntegerField(default=0)
kit_client = models.ForeignKey(Client, on_delete=models.CASCADE, related_name='kit_owner')
# connected by foreign key
class Client(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
client_company = models.CharField(max_length=255, default=0)
client_name = models.CharField(max_length=255, default=0)
# connected by many to many field
class Product(models.Model):
product_id = models.IntegerField(default=0)
product_name = models.CharField(max_length=255, default=0)
product_short_code = models.CharField(max_length=255, default=0)
product_description = models.CharField(max_length=255, default=0)
template:
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<h2 class="mb-3">Add a new Kit</h2>
<div class="row">
<div class="col-md-6 col-sm-8 col-12">
<form method="post" novalidate>
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-success">Save</button>
<a href="{% url 'employee:products_table' %}" class="btn btn-outline-secondary" role="button">Nevermind</a>
</form>
</div>
</div>
{% endblock %}
Upvotes: 0
Views: 247
Reputation: 4763
Use __str__.
I asked for your code just in case you have some strange setup, but this is probably the easiest way for you to do it.
Change your Product
model to this
class Product(models.Model):
product_id = models.IntegerField(default=0)
product_name = models.CharField(max_length=255, default=0)
product_short_code = models.CharField(max_length=255, default=0)
product_description = models.CharField(max_length=255, default=0)
def __str__(self):
return self.product_name
That will replace the Project Object (1)
with whatever is in the product_name
charfield.
EDIT: See below for a good comment about Python 2.
Upvotes: 2
Reputation: 2412
A fairly simple way to do this would be adding string representation to your models. For example in your product model add:
class Product(models.Model):
product_id = models.IntegerField(default=0)
product_name = models.CharField(max_length=255, default=0)
product_short_code = models.CharField(max_length=255, default=0)
product_description = models.CharField(max_length=255, default=0)
def __str__(self):
return self.product_name
Also, if you can use any of the model's fields in there, so for example if you want both id and name you can do something like:
def __str__(self):
return '{}: {}'.format(self.id, self.product_name)
Upvotes: 3