2016-02-25 2 views
1

Я использую Django и django-restfframework для выполнения следующей задачи. Мне нужны эти 3 модели. (1) Персональная модель для хранения информации о клиенте. (2) Модель датчика и (3) Модель DataPoint. Каждый из них является отношением друг к другу. У человека может быть много датчиков, и каждый датчик может иметь много точек данных, но никогда наоборот. Я создал следующие модели в файле models.py. ..Дизайн модели Django RDBMS для рамки отдыха

class Person(models.Model): 
    first_name = models.CharField(max_length=30, null=False) 
    last_name = models.CharField(max_length=30, null=False) 

class Sensor(models.Model): 
    person = models.ForeignKey(Person, on_delete=models.CASCADE) 
    name = models.CharField(max_length=100, null=False) 
    sensor_id = models.UUIDField(null=True, blank=True) 

class DataPoint(models.Model): 
    sensor = models.ForeignKey(Sensor, on_delete=models.CASCADE) 
    date_time_instance = models.DateTimeField() 
    value = models.DecimalField(max_digits=10, decimal_places=4) 

Serializer.py имеет следующий код ...

class PersonSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = Person 
     fields = ('id', 'first_name', 'last_name') 


class SensorSerializer(serializers.ModelSerializer): 

    person = PersonSerializer() 
    class Meta: 
     model = Sensor 
     fileds = ('id', 'name', 'person') 

class DataPointSerializer(serializers.ModelSerializer): 

    sensor = SensorSerializer() 
    class Meta: 
     model = DataPoint 
     fileds = ('id', 'date_time_instance', 'value', 'sensor') 

views.py имеет следующий код для запроса DataPoint API ...

@api_view(['GET', 'POST']) 
def datapoint_list(request): 
    if request.method == 'GET': 
     dp = DataPoint.objects.all() 
     serializer = DataPointSerializer(dp, many=True) 
     return Response(serializer.data) 

    elif request.method == 'POST': 
     serializer = DataPointSerializer(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) 

Вот мои вопросы: -

  1. Я создал хорошие реляты по схеме базы данных?

  2. Кажется, что, когда я выполняю запрос POST по набору данных, я должен предоставить всем Личность и всю информацию о датчике. Как я могу просто предоставить запрос на данные (временную метку и значение данных), и пусть все остальное позаботится (т. Е. Правильный датчик и проверка человека)?

  3. Помогла ли схема базы данных без привязки? Как ?

  4. Где я могу указать, что все запросы - это запросы JSON в моем приложении django?

Заранее за вашу помощь.

+0

Не могли бы вы пояснить # 2? Я думаю, что я понимаю, что вы имеете в виду, однако запрос POST для конечной точки API-интерфейса datapoint будет создавать совершенно новый datapoint, поэтому Person и Sensor не могут быть известны, если вы не указали их. Если вы хотите обновить datapoint, вы можете принять методы PUT и PATCH. Если вы используете только POST, вы можете написать свой метод 'save()' в DataPointSerializer таким образом, чтобы он анализировал Person и Sensor из URL-адреса. Пример: POST для '/ api/datapoint///', а затем вытащите kwargs из URL при создании (или обновлении, если существует) данных. – dkhaupt

ответ

1

Подумав о вашем вопросе немного больше, я думаю, что вижу, что вы пытаетесь сделать. Не имеет смысла обновлять datapoint (я предполагаю), поэтому POST действительно будет единственным интересным методом создания.

Метод serializer create() вызывается при создании экземпляра сериализатора, поэтому, если вы его переопределите, вы можете указать Датчик, как вам хотелось бы, и об этом позаботятся в save(). Вам просто нужно убедиться, что вы проходите в датчике при создании сериализатора, иначе я не думаю, что есть какой-либо способ правильно установить отношения.

Вот как я это сделаю, предполагая, что датчик указан в URL конечной точки. Это предполагает, что Датчик уже существует, но чтобы сделать его более надежным, вы можете использовать get_or_create() - хотя включение неиспользуемого идентификатора датчика в POST, вероятно, будет сложным/странным, было бы разумнее использовать другую конечную точку для создания нового датчика первый:

views.py:

@api_view(['GET', 'POST']) 
def datapoint_list(self, request): 
    if request.method == 'GET': 
    dp = DataPoint.objects.all() 
    serializer = DataPointSerializer(dp, many=True) 
    return Response(serializer.data) 

    elif request.method == 'POST': 
    serializer = DataPointSerializer(data=request.data, context = {'sensor': self.kwargs['sensor'],}) 
    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) 

serializers.py:

class DataPointSerializer(serializers.ModelSerializer): 

    sensor = SensorSerializer() 
    class Meta: 
     model = DataPoint 
     fileds = ('id', 'date_time_instance', 'value', 'sensor') 

    def create(self, validated_data): 
     sensor = Sensor.objects.get(id=self.context.get('sensor')) 
     datapoint = DataPoint.objects.create(sensor=sensor) 
     value = validated_data.pop('value') 
     datapoint.value = value 
     datapoint.save() 
     return datapoint 

Тогда, если вы выложили value к чему-то вроде /api/<sensor_id>/, который должен работать. Надеюсь, кто-то меня исправит, если я ошибаюсь.

Надеюсь, это поможет - кажется, что вы проходили Сенсор и Личность в ПОСТ раньше, и это должно быть так. Если это не то, что вы искали, просто отредактируйте свой вопрос с более подробной информацией.

Пара отмечает:

Если лицо известно, что может быть частью URL, а также. Если Person является запрашивающим пользователем, эти критерии могут быть просто выведены из запроса и использованы в методе create() - просто передайте запрос в контексте сериализатора.

В настоящее время ваша ветка GET возвращает все DataPoints, но если вы использовали указанный мной URL, вы можете фильтровать идентификатор датчика в URL-адресе. Или, может быть, вы хотите, чтобы все они, трудно сказать, к чему вы стремитесь, без дополнительного контекста.

Если вы хотите, чтобы принять более одного value на POST, вам нужно добавить many=True на сериализатора конкретизации в отрасли POST

EDIT: Я был так сосредоточен на # 2, что я забыл свою вторую точки.

  1. Я думаю, ваша схема мелко-, как я уже сказал, это трудно оценить без какого-либо другого контекста, но от того, что вы сказали о том, как точки данных, датчики и лица относятся, кажется, что идеальная конфигурация ,

  2. Я не знаю достаточно о нереляционных БД, чтобы сказать, но я не понимаю, почему было бы лучше в этом случае.

  3. Я не знаю, что вы можете установить формат запроса по умолчанию, хотя это, безусловно, возможно. Если вы добавляете «/? Format = json» к вашему запросу в конечной точке API, DRF правильно интерпретирует его и возвращает только JSON.

+0

Спасибо за ваш ответ @dkhaupt, вы получили мой вопрос правильно, я хотел знать, есть ли способ не передавать весь человек и сенсорный объект, когда я делаю запрос на отправку для ввода нового дататота. По вашему решению кажется, что я, по крайней мере, должен предоставить идентификатор личности и идентификатор датчика (а не целые объекты) с каждым запросом JSON POST по одному потоку данных, нет никакого способа обойти его. – LuckyStarr

+0

Я уже создал Person и Sensor своими запросами POST, поэтому неизвестных нет. Поэтому, чтобы повторить, мой запрос JSON REST POST имеет заголовок как «Content-Type: application/json», и моя служебная информация JSON POST для моего пакета данных должна иметь это, не так ли? { "sensor_id": 1, "person_id": 1, "value": 1.15, } – LuckyStarr

+0

Я не верю, что вам понадобится '' person_id''- если идентификатор датчика известен, достаточно, так как datapoints не имеют внешнего ключа для Лица. Что происходит, когда вы не указываете '' person_id' из POST? – dkhaupt

Смежные вопросы