Reputation: 43
I am creating an API with Django Rest Framework. You can give a term to the api, it looks up data on a third party API and then everything should be stored to the database. All is handled in user scope and I have two tables, one with the search term and the ID of the user and another with the data received, which has the search_id as a foreing key. I now want that if you send a term to the API everything is stored and you get the search back, with ID and all dates. so far so good. I am now stuck, where I need to save the third party data to the database. The serializer demands the model object at saving and not the serializer from the user input. I tried around, but can't figure out, what I am doing wrong:
models.py:
class Search(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,)
term = models.CharField(max_length=200)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.term
class foundTables(models.Model):
search = models.ForeignKey(Search,
related_name='search',
on_delete=models.CASCADE)
code = models.CharField(max_length=200)
content = models.CharField(max_length=1000)
time = models.CharField(max_length=200, blank=True, default='')
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.content
serializers.py
class SearchSerializer(serializers.ModelSerializer):
class Meta:
model = Search
fields = ['id', 'user', 'term', 'created', 'updated']
read_only_fields = ['id', 'user', 'created', 'updated']
class foundTablesSerializer(serializers.ModelSerializer):
search = serializers.PrimaryKeyRelatedField(read_only=True)
class Meta:
model = foundTables
fields = [
'id',
'search',
'code',
'content',
'time',
'created',
'updated']
read_only_fields = [
'id',
'search',
'created',
'updated']
views.py
class genesisRequestViewSet(viewsets.ModelViewSet):
queryset = Search.objects.all()
serializer_class = SearchSerializer
permission_classes = [permissions.IsAuthenticated]
http_method_names = ['get', 'post']
def get_queryset(self):
user = self.request.user
return Search.objects.filter(user=user).order_by('-created')[:1]
def create(self, request):
user = self.request.user
term = request.data['term']
seria = SearchSerializer(data=self.request.data)
genesis = findRequest()
if seria.is_valid():
# search = Search(user=user, term=term)
# search.save()
seria.save(user=user)
genesis.get(term=term)
if genesis.data['Tables']:
genesisdict = {}
for element in genesis.data['Tables']:
genesisdict['code'] = element['Code']
genesisdict['content'] = element['Content']
genesisdict['time'] = element['Time']
tables = foundTablesSerializer(data=genesisdict)
if tables.is_valid():
tables.save(search=seria)
else:
return Response(tables.errors)
return Response(seria.data)
else:
return Response({"status": "No tables found"})
else:
return Response({"errors": seria.errors})
So, if I use the muted "search=Search..." approach, it would kind of work, but I'd like to use the serializer, of course.
The save method returns an error, that it would need a instance of Search:
ValueError at /api/genesis/
Cannot assign "SearchSerializer(data={'term': 'testterm'}):
id = IntegerField(label='ID', read_only=True)
user = PrimaryKeyRelatedField(read_only=True)
term = CharField(max_length=200)
created = DateTimeField(read_only=True)
updated = DateTimeField(read_only=True)": "foundTables.search" must be a "Search" instance.
Any idea, how I could get the foreign key in the tables serializer?
Upvotes: 0
Views: 818
Reputation: 1211
I don't know I understand your question or not but serializer.save()
return an instance you can change your code like this:
Get your Search instance from save() method:
search_ins = seria.save(user=user)
and use in foundTablesSerializer
like this:
tables.save(search=search_ins)
Upvotes: 1