I'm having slight of a problem while using MoneyField in Django.
I have 2 models: Work and Price. And Price gets Work id as a Foreign Key.
In Postman I'm trying to post a Work with a Price, but I keep getting an error.
Here is my work_model:
from django.db import models
from django.contrib.auth import get_user_model
User = get_user_model()
class Work(models.Model):
user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
name = models.CharField(max_length=200)
length = models.IntegerField(null=True)
width = models.IntegerField(null=True)
def __str__(self):
return "{}".format(self.name)
And here my price_model
from django.db import models
from .model_work import *
from djmoney.models.fields import MoneyField
class Price(models.Model):
work = models.OneToOneField(Work, on_delete=models.CASCADE, related_name='price')
price = MoneyField(max_digits=19, decimal_places=4, default_currency='USD', null=True)
shipping = models.IntegerField(null=True)
total = models.IntegerField(null=True)
def __str__(self):
return "{}".format(self.price)
When I'm posting a Work in Postman:
{
"user":"2",
"name":"work 20",
"price":
[
{
"price":20,
"price_currency":"USD",
"shipping":12,
"total":32
}
],
"length":"50",
"width":"60"
}
I keep getting this error:
ValidationError at /works/
["Invalid value for MoneyField: [OrderedDict([('price', <Money: 20.0000 USD>), ('shipping', 12), ('total', 32)])]."]
I've looked everywhere but can't manage to understand my error, does anyone have a clue?
Thanks for your responses!
UPDATE 1:
Forgot to put the serializers.
Here is my work_serializer:
from rest_framework import serializers
from ..models.model_work import Work
from .serializers_user import *
from .serializers_price import *
class WorkIndexSerializer(serializers.ModelSerializer):
"""
Serializer listing all Works models from DB
"""
user = UserIndexSerializer()
price_set = PriceDetailsSerializer(many=True)
class Meta:
model = Work
fields = [
'id',
'name',
'price_set',
'length',
'width',
]
class WorkCreateSerializer(serializers.ModelSerializer):
"""
Serializer to create a new Works model in DB
"""
price = PriceCreateSerializer(many=True)
class Meta:
model = Work
fields = [
'user',
'name',
'price',
'length',
'width',
]
def create(self, validated_data):
price = Price.objects.create(**validated_data)
work = Work.objects.create(**validated_data)
return work
class WorkDetailsSerializer(serializers.ModelSerializer):
"""
Serializer showing details of a Work model from DB
"""
user = UserIndexSerializer()
class Meta:
model = Work
fields = fields = [
'user',
'name',
'price_set',
'length',
'width',
]
And my price_serializer:
from rest_framework import serializers
from ..models.model_price import Price
class PriceIndexSerializer(serializers.ModelSerializer):
"""
Serializer showing Price information when called by Work GET serializers.
Not showing 'work' field to avoid loop.
"""
class Meta:
model = Price
fields = [
'price',
'shipping',
'total'
]
depth = 1
class PriceDetailsSerializer(serializers.ModelSerializer):
"""
Serializer showing Price information when called by Work GET serializers.
Not showing 'work' field to avoid loop.
"""
class Meta:
model = Price
fields = [
'price',
'shipping',
'total'
]
depth = 1
class PriceCreateSerializer(serializers.ModelSerializer):
"""
Serializer to create a new Price when new Work model is created in DB
"""
class Meta:
model = Price
fields = [
'price',
'shipping',
'total'
]
def create(self, validated_data):
work = Work.objects.create(**validated_data)
return work
Related
I was wondering what the correct way is to serialize data in Django REST API from 2 models connected with ForeignKey.
The situation is: i have a 1st table called NewUsers with the user registrations, and a 2nd table called Ticker with data saved from an external API.
The goal is: create a 3rd table with parts of the 2 tables interconnected - one part is the user loggedin, and the other part is the selection of one crypto object. This new table will then be displayed via Django REST API serializer.
The problem is: this new 3rd table does not display the complete list of values selected by the user.
I have gone through the documentation here https://books.agiliq.com/projects/django-admin-cookbook/en/latest/override_save.html and here https://www.django-rest-framework.org/tutorial/1-serialization/ but could not find a complete solution. What am i missing?
views.py:
from rest_framework import generics
from .serializers import WatchlistSerializer
from ticker.serializers import TickerSerializer
from watchlist.models import SectionWatchlist
from ticker.models import Ticker
import requests
from rest_framework.views import APIView
from rest_framework.decorators import api_view
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
class CreateSectionWatchlist(generics.CreateAPIView):
queryset = SectionWatchlist.objects.all()
serializer_class = WatchlistSerializer
class ListSectionWatchlist(generics.ListAPIView):
queryset = SectionWatchlist.objects.all()
serializer_class = WatchlistSerializer
def get_queryset(self):
queryset = SectionWatchlist.objects.all()
author = self.request.query_params.get('author')
if author:
queryset = queryset.filter(author=author)
return queryset
class DeleteSectionWatchlist(generics.RetrieveDestroyAPIView):
queryset = SectionWatchlist.objects.all()
serializer_class = WatchlistSerializer
models.py:
from django.db import models
from django.conf import settings
from ticker.models import Ticker
class SectionWatchlist(models.Model):
id = models.AutoField(primary_key=True) # auto increment field
tickerlist = models.ForeignKey(Ticker, related_name="tickerinfo", on_delete=models.CASCADE)
crypto = models.CharField(blank=True, null=True, max_length=40)
c_0 = models.FloatField(null=True, blank=True, default=None)
o_0 = models.FloatField(null=True, blank=True, default=None)
percentage = models.FloatField(null=True, blank=True, default=None)
user_name = models.CharField(blank=True, null=True, max_length=40)
author = models.ForeignKey(
settings.AUTH_USER_MODEL, blank=True, null=True,
on_delete=models.CASCADE,
)
serializers.py:
from rest_framework import serializers
from watchlist.models import SectionWatchlist
from ticker.models import Ticker
from ticker.serializers import TickerSerializer
class WatchlistSerializer(serializers.ModelSerializer):
crypto = TickerSerializer()
class Meta:
model = SectionWatchlist
fields = ('id','tickerlist','author', 'crypto')
the Django REST API incomplete response
{
"id": 88,
"tickerlist": 36,
"author": 6,
"crypto": {
"crypto": null,
"c_0": null,
"o_0": null
}
}
]
admin.py:
from django.contrib import admin
from django import forms
from . import models
from ticker.models import Ticker
#admin.register(models.SectionWatchlist)
class WatchlistAdmin(admin.ModelAdmin):
list_display = (
'id',
# 'percentage',
'tickerlist',
# 'user_name',
'author',
'get_crypto',
'get_c_0',
'get_o_0',
)
#admin.display(ordering='watchlist__tickerlist', description='get_crypto')
def get_crypto(self, obj):
return obj.tickerlist.crypto
#admin.display(ordering='watchlist__tickerlist', description='c_0')
def get_c_0(self, obj):
return obj.tickerlist.c_0
#admin.display(ordering='watchlist__tickerlist', description='o_0')
def get_o_0(self, obj):
return obj.tickerlist.o_0
Actually my admin displays the response correctly with complete values:
.
How can I have the serialized response in Django REST API complete?
I think you need to set the serializer for the foreign key fields.
class WatchlistSerializer(serializers.ModelSerializer):
tickerlist= TickerSerializer()
author = UserSerializer()
class Meta:
model = SectionWatchlist
fields = ('id', 'tickerlist', 'author', 'crypto')
I am currently using Django REST framework 3.11.0 with Django 3.0.6. I am still very new to DRF and I am not sure how to approach this problem. I am trying to apply sort to SerializerMethodField and an enum. I was able to find some documentation that states that I could make my own OrderFilter but I dont know how. Are there any examples I could use? Here is my code.
View
from rest_framework import generics
from V1.assets.models.asset_main import Asset
from V1.assets.serializers.asset_serializer import AssetSerializer
from rest_framework import filters
from django_filters.rest_framework import DjangoFilterBackend
class AssetsView(generics.ListCreateAPIView):
queryset = Asset.objects.all()
serializer_class = AssetSerializer
filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
filter_fields = ['asset_type']
search_fields = ['asset_type', 'asset_properties', 'current_employee_name']
Model
class AssetType(models.TextChoices):
LAPTOP = 'LPT', _('Laptop')
MOUSE = 'MSE', _('Mouse')
MONITOR = 'MTR', _('Monitor')
AC_ADAPTER = 'ADR', _('AC Adapter')
TELEPHONE = 'TLP', _('Telephone')
LOCK = 'LCK', _('Lock')
HEADSET = 'HDS', _('Headset')
class Asset(CreatedModified):
asset_type = models.CharField(
max_length=3,
choices=AssetType.choices,
default=None
)
asset_properties = JSONField(default=dict)
current_employee = models.ForeignKey(
Employee,
related_name='assets_current_employees',
related_query_name='assets_current_employee',
default=None,
on_delete=models.CASCADE,
null=True,
blank=True
)
class Meta:
app_label = 'assets'
default_related_name = 'assets'
def __str__(self):
return self.asset_type
Serializer
from V1.general.enums import AssetStatus, AssetType
from V1.accounts.models.employee_main import Employee
class AssetSerializer(serializers.ModelSerializer):
current_employee_name = serializers.SerializerMethodField('get_full_name_from_employee')
asset_type = serializers.CharField(source='get_asset_type_display')
class Meta:
model = Asset
fields = (
'id',
'asset_type',
'asset_properties',
'current_employee',
'current_employee_name'
)
extra_kwargs = {
'asset_type': {
'required': True,
'allow_blank': False
}
}
def get_full_name_from_employee(self, asset):
current_employee_name = asset.current_employee.first_name + ' ' + asset.current_employee.last_name
return current_employee_name
I can't seem to order by current_employee_name or asset_type. What should I do to allow sorting for these two fields?
As far as I can understand from your question you want to order the Assets by the current employee name. Let's take few names for example:
Jean d'Artagnan (first_name: Jean, last_name: d'Artagnan)
Joe Plumber (first_name: Joe, last_name: Plumber)
Jonas Meyer (first_name: Jonas, last_name: Meyer)
The same ordering can be achieved if we sort first by first_name and then by last_name. In case there are multiple entries with the same first_name the ordering will be done be the last_name.
To achieve this you can simply specify the ordering_fields in your view:
class AssetsView(generics.ListCreateAPIView):
filters = [filters.OrderingFilter]
ordering_fields = ['current_employee.first_name', 'current_employee.last_name']
I am a beginner in Django. Right now, I am working with the APIs. I am facing a problem. I can't view the string value one of the fields, called label, at http://127.0.0.1:8000/gameapi/. Instead of seeing "label_tag": "racing", I am seeing "label_tag": [2]. Here is the screenshot:
Here are my codes of serializers.py located inside gamreview folder.
from rest_framework import serializers
from .models import Game, Tags
# class TagSerializer(serializers.ModelSerializer):
# class Meta:
# model = Tags
# fields = ['label']
class GameSerializer(serializers.ModelSerializer):
# label_tag = TagSerializer(many=True)
class Meta:
model = Game
# fields = ['id', 'title', 'developer', 'platform']
fields = ['id', 'title', 'developer', 'platform','label_tag']
def create(self, validated_data):
label_tag_data = validated_data.pop('label_tag')
game = Game.objects.create(**validated_data)
for tags_data in label_tag_data:
Tags.objects.create(game=game, **tags_data)
return Game.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.title = validated_data.get('title', instance.title)
instance.developer = validated_data.get('developer', instance.developer)
instance.platform = validated_data.get('platform', instance.platform)
# instance.tag = TagSerializer(read_only=True, many=True)
instance.save()
return instance
Here are my codes of models.py under gamreview folder:
from django.db import models
from django.template.defaultfilters import slugify
# Create your models here.
class Tags(models.Model):
label = models.CharField(max_length=20)
def __str__(self):
return self.label
class Game(models.Model):
title = models.CharField(max_length=100)
developer = models.CharField(max_length=100)
platform = models.CharField(max_length=50, default='null')
label_tag = models.ManyToManyField(Tags)
slug = models.SlugField(max_length=150, default='null')
def __str__(self):
return self.title
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super().save(*args, **kwargs)
class Review(models.Model):
game = models.ForeignKey(Game, on_delete=models.CASCADE)
review = models.CharField(max_length=1000)
date = models.DateField(auto_now=True)
slug = models.SlugField(max_length=150, default='null')
def __str__(self):
return self.game
Here are my codes of views.py under gamreview folder:
from django.views import generic
from .models import Game
from rest_framework import generics
from .serializers import GameSerializer
# Create your views here.
class GameListView(generic.ListView):
template_name = 'gamereview/gamelist.html'
context_object_name = 'all_games'
def get_queryset(self):
return Game.objects.all()
class ReviewView(generic.DetailView):
model = Game
template_name = 'gamereview/review.html'
# class GameApiView(generics.ListAPIView):
class GameApiView(generics.ListCreateAPIView):
queryset = Game.objects.all()
serializer_class = GameSerializer
class GameDetailApiView(generics.RetrieveUpdateDestroyAPIView):
queryset = Game.objects.all()
serializer_class = GameSerializer
Here are my codes of urls.py under gamreview folder:
from . import views
from django.urls import path
app_name = 'gamereview'
urlpatterns = [
path('gamereview/', views.GameListView.as_view(), name='gamelist'),
path('gamereview/<slug:slug>/', views.ReviewView.as_view(), name='review'),
path('gameapi/', views.GameApiView.as_view(), name='gamelistapi'),
path('gameapi/<int:pk>/', views.GameDetailApiView.as_view()),
]
I don't get any error while running the server. However, "label_tag": "racing"is not showing up.
How can I fix the issue?
in Game model change label_tag to
label_tag = models.ManyToManyField(Tags, related_name='tags')
this can be considered as tags is a field for a Game model
your serializer classes should be
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tags
fields = ['label']
class GameSerializer(serializers.ModelSerializer):
tags= TagSerializer(many=True)
class Meta:
model = Game
# fields = ['id', 'title', 'developer', 'platform']
fields = ['id', 'title', 'developer', 'platform','tags']
you will get tags as a list of tags objects every tag have a label field with string value
'tags': [
{
'label': 'etc'
},
{
'label': 'etc2'
}
]
if you want tags like
'tags': [
'etc',
'etc'
]
this code will help you
```python
class GameSerializer(serializers.ModelSerializer):
label_tags = serializers.SerializerMethodField()
class Meta:
model = Game
# fields = ['id', 'title', 'developer', 'platform']
fields = ['id', 'title', 'developer', 'platform','label_tags']
def get_label_tags(self, game):
new_tags = []
tags = game.label_tag.all()
for tag in tags:
new_tags.append(tag.label)
return new_tags
You can use the source argument
class GameSerializer(serializers.ModelSerializer):
label_tag = serializers.ReadOnlyField(source='label.label')
class Meta:
model = Game
fields = ['id', 'title', 'developer', 'platform','label_tag']
another way is to use a SerializerMethodField like this(it's an overkill in this case I believe)
class GameSerializer(serializers.ModelSerializer):
label_tag = serializers.SerializerMethodField()
class Meta:
model = Game
fields = ['id', 'title', 'developer', 'platform','label_tag']
def get_label_tag(self, obj):
return obj.label.label
check similar answers here DRF source argument
I'm creating this simple shopping API in Django REST.
Internally I'm using IDs for foreign key constraints, while guuids are brought to the outside world.
For the checkout procedure, the user provides a list of article IDs he is willing to purchase. The object in the POST data thus looks as follows:
{
assets: [
{
'product': 'd9d5044d-2284-4d15-aa76-2eee3675035b',
'amount': 4
},
....
]
}
I'm using the following ticket/asset models:
# Ticket
class Ticket(models.Model):
uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='tickets', on_delete=models.CASCADE)
# Assets
class Asset(models.Model):
ticket = models.ForeignKey(Ticket, related_name='assets', on_delete=models.CASCADE)
stock_item = models.ForeignKey(Stock, related_name='stock_item', on_delete=models.SET_NULL, null=True)
amount = models.IntegerField(validators=[MinValueValidator(0)])
And the serializers look as follows:
# Asset serializer
class AssetSerializer(serializers.ModelSerializer):
class Meta:
model = Asset
fields = ('stock_item', 'amount')
# Ticket serializer
class TicketSerializer(WritableNestedModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
assets = AssetSerializer(many=True)
class Meta:
model = Ticket
fields = ('uuid', 'owner', 'assets', )
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
When posting an object of the type specified above, the following error is presented:
{"assets":[{"stock_item": ["Invalid type. Expected PK, received string"]}]}
Which I can't seem to solve, how do I instruct the serializer to use the uuid as the lookup value? I solved a similar problem on view-level earlier by using the lookup_field member, but that doesn't seem to solve it. Any suggestions?
Enter code here
If I have understood you correctly, a SlugRelatedField should be able to find the correct related object.
class AssetSerializer(serializers.ModelSerializer):
ticket = serializers.SlugRelatedField(
read_only=True,
slug_field='uuid',
queryset=Ticket.objects.all() # Might be redundant with read_only=True
)
class Meta:
model = Asset
fields = ('ticket', 'stock_item', 'amount')
Elaborating on #BjornW's comment:
class UUIDRelatedField(serializers.SlugRelatedField):
slug_field = 'uuid'
def __init__(self, **kwargs):
super().__init__(slug_field=self.slug_field, **kwargs)
def to_representation(self, obj):
return getattr(obj, self.slug_field).hex
I am confusing how can I write the filter code in my serializers.py.
I have the following models.
User (AbstractBaseUser)
userid = models.CharField(max_length=64, primary_key=True)
username = models.CharField(max_length=128)
Clinic (models.Model)
clinic_id = models.CharField(max_length=8, primary_key=True)
clinic_name = models.CharField(max_length=64)
Consultation (models.Model)
consultation_id = models.AutoField(primary_key=True)
clinic_id = models.ForeignKey(Clinic)
user = models.ForeignKey(User)
Chat (models.Model)
chat_id = models.AutoField(primary_key=True)
consultation_id = models.ForeignKey(Consultation)
DIDRESPONSE_CHOICE = {
('R', 'No'),
('C', 'Doing'),
('F', 'Done'),
}
did_response = models.CharField(max_length=1, choices=DIDRESPONSE_CHOICE, default='N')
ChatDetail (models.Model)
chat_no = models.AutoField(primary_key=True)
chat_id = models.ForeignKey(Chat)
CHATFROM_CHOICE = {
('D', 'Doctor'),
('U', 'User'),
}
chat_from = models.CharField(max_length=1, blank=True, null=True)
chat = models.CharField(max_length=512, blank=True)
I want to serialize above data and response to client in JSON format.
{
'username': 'Tom Smith',
'clinic_name': 'Adam's clinic',
'consultation_id': 12345678,
'chat_id': 09876543,
'chat_detail' : [
{'chat_no': 11122233, 'chat_from': 'D', 'chat': 'How are you doing today?'},
{'chat_no': 11112234, 'chat_from': 'U', 'chat': 'I have a headache'},
{'chat_no': 11122235, 'chat_from': 'D', 'chat': 'Oh, I'm sorry'},
{'chat_no': 11122236, 'chat_from': 'U', 'chat': 'Can you help me?'},
]
}
I made filters in my views.py by using override get_queryset method. But it wasn't not work. So, I tried to write filters in my serializers.py. But it is also didn't work(I don't understand how can I write above requirement filter in my serializers.py).
What should I do to achieve my requirement? Please help me please.
views.py
class WebViewChatDataOutputView(APIView):
def get(self, request, format=None):
chat_detail = ChatDetail
serializer = WebViewChatDataOutputSerializer(chat_detail, many=True)
filter_fields = ('chat_id')
return Response(serializer.data)
def get_queryset(self):
consultation_id = self.request.consultation_id
chat = Chat.objects.filter(consultation_id=consultation_id)
return ChatDetail.objects.filter(chat_id=chat.chat_id)
serializers.py
class WebViewChatDataOutputSerializer(serializers.ModelSerializer):
# class Meta:
# model = Consultation
# fields = ('consultation_id')
#
# class Meta:
# model = Chat
# fields = ('chat_id')
#
class Meta:
chat = ChatDataForChatDetailSerializer(many=True)
model = ChatDetail
fields = ('chat_no', 'chat_from', 'chat')
I am trying to make a filter. But I got 'Meta.fields'; contains fields that are not defined on this FilterSet: ChatDetail, Chat" error.
My view is the following.
from .filtering import CategoryFilter
class WebViewChatDataOutputView(generics.RetrieveAPIView):
def get(self, request, format=None):
filter_backends = (
rest_framework.filters.OrderingFilter,
rest_framework.filters.DjangoFilterBackend
)
filter_class = CategoryFilter
serializer = WebViewChatDataInputSerializer(chat_detail, many=True)
return Response(serializer_class.data)
And my filtering.py is the following.
class CategoryFilter(rest_framework.filters.FilterSet):
name = django_filters.CharFilter(
name=ChatDetail,
lookup_expr='chat_id'
)
parent_category_name = django_filters.CharFilter(
name=Chat,
lookup_expr='chat_id'
)
class Meta:
model = ChatDetail
fields = ['ChatDetail', 'Chat']
Did I mistake any kind of grammar? Please gime an advice.
I updated my code.
views.py
class WebViewChatDataOutputView(generics.RetrieveAPIView):
def get(self, request, format=None):
lookup_field = 'chat_id'
queryset = Chat.objects.all()
serializer_class = ChatSerializer
return Response(serializer_class.data)
serializers.py
class ChatDetailSerializer(serializers.ModelSerializer):
class Meta:
model = ChatDetail
fields = '__all__'
class ChatSerializer(serializers.ModelSerializer):
username = serializers.CharField(source='consultation_id.user.username') # You should rename the consultation_id foreign key field to consultation, by the way
clinic_name = serializers.CharField(source='consultation_id.clinic_id.clinic_name') # Same goes for clinic_id
chat_detail = ChatDetailSerializer(many=True, source='chatdetail_set')
class Meta:
model = Chat
fields = ('user_name', 'clinic_name', 'consultation_id', 'chat_id', 'chat_detail')
I put below couple solution to achieve filters for your endpoint.
You can use filter_class but to do it use ListApiView. Create filtering.py and add there something(for quick example):
import django_filters
import rest_framework.filters
from categories import models as categories_models
class CategoryFilter(rest_framework.filters.FilterSet):
name = django_filters.CharFilter(
name='name',
lookup_expr='icontains'
)
parent_category_name = django_filters.CharFilter(
name='parent_category__name',
lookup_expr='icontains'
)
class Meta:
model = categories_models.Category
fields = ['name', 'parent_category_name']
In your view add:
import rest_framework.filters
filter_backends = (
rest_framework.filters.OrderingFilter,
rest_framework.filters.DjangoFilterBackend
)
filter_class = categories_filtering.CategoryFilter
More details you find in ListApiView inspector
Its clear because you have another file only with filter logic and its seperated from your serializer.
You can use also **get_queryset but first u need add statment to check url for example:**
url contain q parametr with filter field
in method u need get q value and to something with these
write query to do it
but better idea is to use(u need change to Generic):
Filter_queryset
It seems to me that your problem is not filtering, in the DRF sense or the QuerySet sense, you simply need the right serializers and views for your models.
The output you shared refers to a given Chat. For the serializers, you'll need a ChatSerializer and a ChatDetailSerializer (for the list of ChatDetails).
Your can use the source argument in your serializer fields to retrieve data from your related models, so ChatSerializer could look something like:
class ChatSerializer(serializers.ModelSerializer):
username = serializers.CharField(source='consultation_id.user.username') # You should rename the consultation_id foreign key field to consultation, by the way
clinic_name = serializers.CharField(source='consultation_id.clinic_id.clinic_name') # Same goes for clinic_id
chat_detail = ChatDetailSerializer(many=True, source='chatdetail_set')
class Meta:
model = Chat
fields = ('user_name', 'clinic_name', 'consultation_id', 'chat_id', 'chat_detail')
The ChatDetailSerializer can be a simple ModelSerializer
class ChatDetailSerializer(serializers.ModelSerializer):
class Meta:
model = ChatDetail
fields = '__all__'
In your views, DRF needs to know how to fetch the data. You can use get_queryset for that, but that does nothing if you implement in on an ApiView, use a RetrieveView instead, since you're showing one model instance (a ChatDetail). Or use some other generic view depending on your needs (see the DRF documentation on the subject, http://www.django-rest-framework.org/api-guide/generic-views/#retrieveapiview).
class WebViewChatDataOutputView(generics.RetrieveAPIView):
lookup_field = 'chat_id'
queryset = Chat.objects.all()
serializer_class = ChatSerializer
And that's it. I hope you figure it out.