If I was to have two Django models as shown below with Book related to Category, how else can i show the relation without using a Foreign Key when using Django Rest Framework using PostgreSQL DB to make the Foreign Key field editable in a HTML form?
CATEGORIES = [
('Fiction', ('Fiction')),
('Non-Fiction', ('Non-Fiction'))
]
class Category(models.Model):
category_name = models.CharField(max_length=255, choices=CATEGORIES)
class Book(models.Model):
title = models.CharField(max_length=255)
author = models.CharField(max_length=255)
pages = models.IntergerField(max_length=255)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
My challenge comes up in the DB when in the book
table the category column in represented as category_id
which are integers. This creates a problem as when performing CRUD functions especially EDIT
since i can't edit the category from the front-end in a form because it's represented as i.e. 1,2,3.....
instead of the actual categories. I want to achieve this with a REST API.
My serializer
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
My API views
@api_view(['POST'])
def AddBookAPI(request):
serializer = BookSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['PUT'])
def EditBookAPI(request, id):
book_record =get_object_or_404(Book, id=id)
serializer = BookSerializer(instance=book_record, data=request.data)
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_304_NOT_MODIFIED)
@api_view(['DELETE'])
def DeleteBookAPI(request, id):
book = get_object_or_404(Book, id=id)
book.delete()
return Response('Book Record Successfully Deleted!', status=status.HTTP_200_OK)
And a sample response
{
"id": 1,
"title": "The Green Light",
"author": "Peris Fuller",
"pages": 456,
"category": 2,
},
Any help on this would be appreciated.
CodePudding user response:
It may be okay to have the id
for categories
.
If you want to edit from the frontend, make a get
request to get all categories (you did not report category
serializer, but there must be id
and category_name
).
I guess you want to change categories via a select menu. If so, associate each option with the id
of each category as a value and the category_name
of each category as the text to be displayed.
When you go to edit the model, you will serialize id
again, but you will be able to read the category_name
.
CodePudding user response:
Add __str__
or __unicode__
methods in your models that will help you to show the name instead of id on the UI.
Like this shared the example of both methods:-
class Category(models.Model):
category_name = models.CharField(max_length=255, choices=CATEGORIES)
def __unicode__(self):
return self.category_name
def __str__(self):
return self.category_name
In your BookSerializer
you can lookup for the id or name into the Category
model and map the values accordingly.