2017-11-22 27 views
0

Django Rest Frameworkに問題があります。私が構築しているこのアプリはアバターです。ユーザーは自分のアバターを更新し、私が定義したパス(/users_id/photoset_id/filename.png)でアバターを自動保存することができます。だから私は、このコードのように保存するように機能しますDjango Restフレームワーク:重複キー値が一意制約に違反しています

def avatar_file_path(instance, filename): 
    ext = filename.split('.')[-1] 
    filename = '%s.%s' % (instance.id, ext) 
    return "users/%s/avatar/%s_%s" %(instance.user.id, instance.photoset.id, filename) 

class Avatar(models.Model): 
    user = models.ForeignKey(User, related_name='avatar_set', null=True) 
    photoset = models.ForeignKey(PhotoSet, null=True, blank=True) 
    primary = models.BooleanField(default=True) 
    caption = models.TextField(blank=True, null=True) 
    image = models.ImageField(max_length=1024, upload_to=avatar_file_path) 
    is_public = models.BooleanField(_('is public'), default=True, help_text=_('Public photographs will be displayed in the default views.')) 
    date_uploaded = models.DateTimeField(default=datetime.datetime.now) 

    def save(self, force_insert=False, force_update=False, *args, **kwargs): 
     # Make one primary Avatar 
     if self.primary: 
      avatars = Avatar.objects.filter(user=self.user, primary=True).exclude(id=self.id) 
      avatars.update(primary=False) 
     # Set default photoset 
     if self.photoset is None: 
      if not PhotoSet.objects.filter(user=self.user, photoset_type=3).exists(): 
       PhotoSet.objects.create(user=self.user, photoset_type=3, title='Profile Pictures') 
       self.photoset = PhotoSet.objects.get(user=self.user, photoset_type=3) 
      if PhotoSet.objects.filter(user=self.user, photoset_type=3).exists(): 
       self.photoset = PhotoSet.objects.get(user=self.user, photoset_type=3) 
     # Model Save override 
     if self.id is None: 
      saved_image = self.image 
      self.image = None 
      super(Avatar, self).save(*args, **kwargs) 
      self.image = saved_image 
     super(Avatar, self).save(force_insert, force_update, *args, **kwargs) 

私はシリアライザは、Djangoの残りのフレームワークでPOSTを作成する場合:

class AvatarCreateUpdateSerializer(ModelSerializer): 
    class Meta: 
     model = Avatar 
     fields = [ 
      'user', 
      'image', 
      'caption', 
      'is_public', 
     ] 

それは問題を行く:行の enter image description here

エラーログの追跡:super(Avatar, self).save(force_insert, force_update, *args, **kwargs)

なぜ私はこの問題に直面するのですか私はこれを修正できますか?前もって感謝します!

答えて

3

あなたは、あなたのモデルのベースクラス上の2回save()メソッド呼び出している:以下のコメントは、あなたが、言うように

super(Avatar, self).save(force_insert, force_update, *args, **kwargs) 

:ここ

super(Avatar, self).save(*args, **kwargs) 

そして、ここをこのようなケースを処理するには、update_or_createまたはget_or_createを使用する必要があります。固定

+1

そして、基本的にそれを保存するのではなく、アップデートを使うこともできます:https://stackoverflow.com/questions/6382806/django-save-update-on-duplicate-key – user1767754

+0

この行を削除すると、super(アバター、自己).save(* args、** kwargs)。私はパスにavatar_idでpresaveを傾ける。ファイルパス:users/1/avatar/1_None.jpg代わりにusers/1/avatar/1_9.jpg(9はavatar_id) –

+0

@Clementこの行をget_or_createに修正するのに役立ちますか? Bro –

0

問題:super(Avatar, self).save(*args, **kwargs)

0

問題への変更super(Avatar, self).save(force_insert, force_update, *args, **kwargs)はセーブ機能は、残りのフレームワークによって、「forced_insert = True」を渡されるということです。同じデータで2回保存すると、同じプライマリキーを強制的に2回挿入しようとしています。

溶液は、第保存する第二前

kwargs['force_insert'] = False 

添加することによって、そのforced_insertをリセットするために、後に保存することです。これにより、Djangoはupdateメソッドを使用できるようになります。したがって、同じプライマリキーを2度試して作成しないでください。

関連する問題