2017-06-14 72 views
1

当我发送json到我的序列化程序时,除了有外键关系的一个字段外,所有字段都会保存。Django休息框架不能保存外键

我的设置是如下:

型号

class Day(models.Model): 
    date = models.DateField(auto_now=False, auto_now_add=False) 
    price = models.FloatField() 
    paymentMethod = models.CharField(max_length = 200) 

def __unicode__(self): 
    return str(self.date) 

class Reservation(models.Model): 
    start = models.DateField(verbose_name='Заезд', auto_now=False, auto_now_add=False, blank=False) 
    end = models.DateField(verbose_name='Выезд', auto_now=False, auto_now_add=False, blank=False) 
    check_in_time = models.TimeField(verbose_name='Время заезда', blank=False) 
    check_out_time = models.TimeField(verbose_name='Время выезда', blank=False) 
    has_refund = models.BooleanField(verbose_name='Возвратная бронь', default=True) 
    payed = models.BooleanField(verbose_name='Оплачено', default=False) 
    room = models.ForeignKey('Room', null=True, blank=True, verbose_name='Номер', on_delete=models.CASCADE) 
    reserved_days = models.ManyToManyField(Day, blank=False) 
    guest_name = models.CharField(verbose_name='Имя гостя', max_length=200, blank=True) 
    reservation_number = models.CharField(verbose_name='Номер брони', max_length=200, blank=True) 


class Room(models.Model): 
    name = models.CharField(max_length = 200, null=True) 

def __unicode__(self): 
    return self.name 

串行器

class DaySerializer(serializers.ModelSerializer): 
class Meta: 
    model = Day 
    fields = [ 
     'date', 
     'price', 
     'paymentMethod', 
    ] 

class RoomSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Room 
     fields = [ 
      'id', 
      'name', 
     ] 

class ReservationSerializer(serializers.ModelSerializer): 
    room = RoomSerializer 
    reserved_days = DaySerializer(many=True) 

    class Meta: 
     model = Reservation 
     fields = [ 
      'start', 
      'end', 
      'check_in_time', 
      'check_out_time', 
      'reserved_days', 
      'room', 
      'has_refund', 
      'payed', 
      'guest_name', 
      'reservation_number', 
     ] 

    def create(self, validated_data): 
     day_data = validated_data.pop('reserved_days') 
     room = validated_data.pop('room') 

     reservation = Reservation.objects.create(**validated_data) 
     existing_room = Room.objects.get_or_create(pk=room.pk) 
     reservation.room = existing_room 

     for day in day_data: 
      day, created = Day.objects.get_or_create(date=day['date'], price=day['price'], paymentMethod=day['paymentMethod']) 
      reservation.reserved_days.add(day) 
     return reservation 

JSON,我送

{ 
    "start": "2017-12-12", 
    "end": "2017-12-12", 
    "has_refund": false, 
    "room": 0, 
    "reserved_days": [ { 
     "date": "2017-12-12", 
     "price": "2", 
     "paymentMethod": "3" 
    }, 
    { 
     "date": "2017-12-13", 
     "price": "2", 
     "paymentMethod": "3" 
    } 
    ], 
    "check_in_time": "14:00", 
    "check_out_time": "12:00", 
    "guest_name": "Ivan", 
    "payed": false 
    } 

响应

ValueError at /core/create/ 
Cannot assign "(<Room: kremlin>, False)": "Reservation.room" must be a "Room" instance. 

UPDATE

工作串行

def create(self, validated_data): 
    day_data = validated_data.pop('reserved_days') 
    room = validated_data.pop('room') 

    reservation = Reservation.objects.create(**validated_data) 
    existing_room = Room.objects.get(name=room['name']) 
    reservation.room = existing_room 
    reservation.save() 

    for day in day_data: 
     day, created = Day.objects.get_or_create(date=day['date'], price=day['price'], paymentMethod=day['paymentMethod']) 
     reservation.reserved_days.add(day) 
    return reservation 
+0

是否尝试将'room = RoomSerializer'更改为'room = RoomSerializer()' –

回答

1

get_or_create返回(对象,创建)的元组,这样解释你的错误。
回答以下是编辑

你的代码更看我注意到,你在创建Reservation第一&然后分配房间,但从来没有储蓄。我已经改变了它,以便首先得到房间并将其添加到验证的数据中,以便正确保存。

class ReservationSerializer(serializers.ModelSerializer): 
    room = RoomSerializer() 

    def create(self, validated_data): 
     day_data = validated_data.pop('reserved_days') 
     room = validated_data.pop('room') 

     if room.pk: 
      room_id = room.pk 
     else: 
      room_id = Room.objects.create(name=room.name).id 
     validated_data["room_id"] = room_id 

     reservation = Reservation.objects.create(**validated_data) 

     for day in day_data: 
      day, created = Day.objects.get_or_create(date=day['date'], price=day['price'], paymentMethod=day['paymentMethod']) 
      reservation.reserved_days.add(day) 
     return reservation 

另外请记住,get_or_create这是很容易出现竞争条件,可能导致多个行同时插入相同的参数。