Marco
Marco

Reputation: 55

http POST containing a foreign key and save it

I send http request post from client. Code client.

import requests
payload = {'data':['12', '15'], 'timestamp':['1', '2'], 'mission':['Mission01', 'Mission01']}
r = requests.post("http://127.0.0.1:8000", data=payload)
print(r.url)

I receive in Django http post:

My models.py

from django.db import models

class Mission(models.Model):
    name = models.CharField(max_length=250)
    description = models.CharField(max_length=1000)
    type = models.CharField(max_length=500)
    date = models.DateField()

    def __str__(self):
        return self.name + '-' + self.description

class SensorLog (models.Model):
    mission = models.ForeignKey(Mission, on_delete=models.CASCADE)
    data = models.CharField(max_length=50)
    timestamp = models.CharField(max_length=50)

my views.py

from django.shortcuts import render
from django.http import Http404, HttpResponse
from django.views.decorators.csrf import csrf_exempt
from .models import Mission, SensorLog

@csrf_exempt
def home(request):
    context = {'request_method': request.method}
    if request.method == 'POST':
        datas = request.POST.getlist('data')
        timestamps = request.POST.getlist('timestamp')
        missions = request.POST.getlist('mission')
        for i in range(len(datas)):
           post = SensorLog.objects.create(data=datas[i], timestamp=timestamps[i], mission=missions[i])
    return render(request, 'your_template_name_here', context)

If I run django and client.. In django i have error:

ValueError: Cannot assign "'Mission01'": "SensorLog.mission" must be a "Mission" instance.

why don't i save data? why have i this error? How can i do?

Upvotes: 0

Views: 205

Answers (1)

Henry Woody
Henry Woody

Reputation: 15672

The problem is that when you use SensorLog.objects.create(data=datas[i], timestamp=timestamps[i], mission=missions[i]), the constructor is expecting a Mission instance, but you're providing a string.

To solve this you can either lookup the Mission by name before, or just pass in the id of the Mission and use the mission_id keyword arg in the SensorLog constructor.

Using the names (in your home method):

for i in range(len(datas)):
    mission = Mission.objects.get(name=missions[i])
    post = SensorLog.objects.create(data=datas[i], timestamp=timestamps[i], mission=mission)

Using ids:

payload = {'data':['12', '15'], 'timestamp':['1', '2'], 'mission_ids':[1, 2]}

Then in the home method:

for i in range(len(datas)):
    post = SensorLog.objects.create(data=datas[i], timestamp=timestamps[i], mission_id=mission_ids[i])

Upvotes: 2

Related Questions