I have two models
class Properties(models.Model):
property_name = models.CharField(max_length=100)
property_type = models.CharField(choices=TYPE, max_length=50)
property_location = models.CharField(max_length=100)
county = models.CharField(choices=COUNTY, max_length=50)
number_of_units = models.IntegerField()
date_created = models.DateField(auto_now_add=True)
last_modified = models.DateField(auto_now=True)
def __str__(self):
return self.property_name
class Meta:
verbose_name_plural = "Properties"
class RentalUnits(models.Model):
unit_number = models.CharField(max_length=10)
property = models.ForeignKey(Properties, on_delete=models.CASCADE)
no_of_bedrooms = models.IntegerField(default=0)
no_of_bathrooms = models.IntegerField(default=0)
rent_per_month = models.IntegerField(default=0)
status = models.CharField(max_length=20, choices=STATUS)
date_created = models.DateField(auto_now_add=True)
last_modified = models.DateField(auto_now=True)
def __str__(self):
return self.unit_number
class Meta:
verbose_name_plural = 'Units'
And their corresponding serializers
class PropertiesSerializers(serializers.ModelSerializer):
class Meta:
model = Properties
fields = '__all__'
class RentalUnitsSerializers(serializers.ModelSerializer):
property = serializers.SerializerMethodField()
class Meta:
model = RentalUnits
fields = ('id', 'unit_number', 'property', 'no_of_bedrooms', 'no_of_bathrooms', 'rent_per_month', 'status',)
I wanted to show their foreign key names instead of IDs in a datatable and I found a good solution here so i ended up using
def to_representation(self, instance):
rep = super(RentalUnitsSerializers, self).to_representation(instance)
rep['property'] = instance.property.property_name
return rep
and it gave me this
{
"id": 12,
"unit_number": "1A",
"property": 1,
"no_of_bedrooms": 3,
"no_of_bathrooms": 2,
"rent_per_month": 60000,
"status": "Occupied"
},
{
"id": 12,
"unit_number": "1A",
"property": "New Apartments",
"no_of_bedrooms": 3,
"no_of_bathrooms": 2,
"rent_per_month": 60000,
"status": "Occupied"
},
Adding units & deleting units still works fine. My problem now comes up when I want to edit the rental unit details. I'm using jQuery and AJAX to populate my data table & forms via API. With the addition of def to_representation(self, instance):
to the Rental Unit serializer, the data table populates with Foreign Key names, but the property field is left blank when the edit form loads, and the foreign key field name does not apprear in that input field. However, when I remove this def to_representation(self, instance):
the property input field & data table is populated with the property Foreign Key and successful editing resumes. Here is my jQuery code for editing:
//Edit Units API
$('#RentalUnits-Records').on('click', '.update', function(e){
e.preventDefault();
let id = $(this).attr('id');
$('input[id=unitID]').val(id);
console.log(id)
let myurl = "http://127.0.0.1:8000/api/units/"+id+"/";
$.ajax({
async: true,
url:myurl,
method:'GET',
success: function(result){
$('input[name="unit_number"]').val(result.unit_number);
$('input[name="property"]').val(result.property);
$('input[name="no_of_bedrooms"]').val(result.no_of_bedrooms);
$('input[name="no_of_bathrooms"]').val(result.no_of_bathrooms);
$('input[name="rent_per_month"]').val(result.rent_per_month);
$('select[name="status"]').val(result.status);
}
});
$( "#u-number" ).change(function() {
$('input[name=unit_number]').val($(this).val());
});
$( "#u-property" ).change(function() {
$('input[name=property]').val($(this).val());
});
$( "#u-bedrooms" ).change(function() {
$('input[name=no_of_bedrooms]').val($(this).val());
});
$( "#u-bathrooms" ).change(function() {
$('input[name=no_of_bathrooms]').val($(this).val());
});
$( "#u-rent" ).change(function() {
$('input[name=rent_per_month]').val($(this).val());
});
$( "#u-status" ).change(function() {
$('select[name=status]').val($(this).val());
});
});
//Save Edited Rental Unit Button
$(function() {
$('#editUnit').on('submit', function(e) {
e.preventDefault();
let id = $("#unitID").attr("value");
console.log(id);
let myurl = "http://127.0.0.1:8000/api/units/edit/"+id+"/";
$.ajax({
type : 'PUT',
url : myurl,
data : $("#editUnit :input").serializeArray(),
dataType: "json",
success: function(data){
alert("Unit Details Updated!");
location.reload();
},
error:function(data){
alert("Unit Details Not Updated!");
location.reload();
}
});
});
});
});
And the edit form:
<form id="editUnit" action="">
{% csrf_token %}
<div class="mb-3">
<input type="hidden" id="unitID" value="">
</div>
<div class="mb-3">
<label>Unit Number</label>
<input type="text" class="form-control" name="unit_number" id="u-number" placeholder="Unit Number">
</div>
<div class="mb-3">
<label>Associated Property</label>
<input type="number" class="form-control" name="property" id="u-property" placeholder="Property" readonly>
</div>
<div class="mb-3">
<label>No. of Bedrooms</label>
<input type="number" class="form-control" name="no_of_bedrooms" id="u-bedrooms" placeholder="No. of Bedrooms">
</div>
<div class="mb-3">
<label>No. of Bathrooms</label>
<input type="number" class="form-control" name="no_of_bathrooms" id="u-bathrooms" placeholder="No. of Bathrooms">
</div>
<div class="mb-3">
<label>Rent</label>
<input type="number" class="form-control" name="rent_per_month" id="u-rent" placeholder="Rent Per Month">
</div>
<div class="mb-3">
<label>Status</label>
<select class="form-select" name="status" id="u-status" aria-label="Default select example" placeholder="Associated Property">
<option selected disabled>Status</option>
<option value="Occupied">Occupied</option>
<option value="Under Maintenance">Under Maintenance</option>
<option value="Vacant">Vacant</option>
</select>
</div>
<div class="mb-3">
<button class="btn btn-soft-success btn-sm" id="u-edit" type="submit">Save Changes</button>
<button class="btn btn-soft-secondary btn-sm" type="button" data-bs-dismiss="modal">Cancel</button>
</div>
</form>
QUESTION: How do I show the Foreign Key field name
instead of ID
in the data table and modal edit form but still maintain the property_id
in the DB. I read somewhere it's bad practice to have foreign fields using strings instead of IDs?
ALSO some help in figuring out how to display the Properties in a dropdown list
incase there is more than one property would be helpful to allow for a user to change that as well. As of now its readonly
. Any help on this would be highly appreciated. Thank you.