在Django中保存模型时发送当前用户

Bog*_*che 0 python django django-rest-framework

从Django 1.7升级到1.10以及Django Rest Framework 3.5.4后,我遇到了一个问题.问题是,当我尝试声明凭证时,endopint/calims返回500错误,文本为:IntegrityError at/claims(1048,"Column'user_id'不能为null")

在urls.py中添加如下路由:

url('^claims', v.ClaimList.as_view(), name='claim_list')
Run Code Online (Sandbox Code Playgroud)

而views.py文件中的相关部分是:

class ClaimSerializer(serializers.ModelSerializer):
    company_name = s.ReadOnlyField(source="ad.company.name")
    company_address = s.ReadOnlyField(source="ad.company.address")

    ad_thumbnail = ThumbnailField(source="ad.picture", size="200x200", read_only=True)

    class Meta:
        exclude = ('user',)
        model = m.Claim


class ClaimSerializerDeep(ClaimSerializer):

    class Meta:
        exclude = ('user',)
        model = m.Claim
        depth = 2


class ClaimSerializerFlat(ClaimSerializer):
    class Meta:
        exclude = ('user',)
        model = m.Claim


@permission_classes((IsAuthenticated,))
class ClaimList(Limitable, generics.ListCreateAPIView):
    model = m.Claim

    def get_queryset(self):
        tab = self.request.GET.get("tab", "active")
        q = m.Claim.objects.filter(user=self.request.user.pk)
        if tab == "active":
            q = q.filter(redeemed=False, ad__end__gte=dt.date.today())
        elif tab == "used":
            q = q.filter(redeemed=True)
        return self.limit(q)

    def pre_save(self, obj):
        obj.user = self.request.user

    def get_serializer_class(self):
        if self.request.method == "POST":
            return ClaimSerializerFlat
        else:
            return ClaimSerializerDeep
Run Code Online (Sandbox Code Playgroud)

索赔模型是:

class Claim(models.Model):
    ad = models.ForeignKey("Ad")
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    created = models.DateTimeField(auto_now_add=True)
    redeemed = models.BooleanField(default=False)

    def save(self, *args, **kwargs):
        increase_claimed = False
        if self.pk is None:
            increase_claimed = True
        self.user = User.objects.first() # Temporary hack so that it won't crash
        super(Claim, self).save(*args, **kwargs) # here is where it crashes 
        if increase_claimed:
            self.ad.claimed += 1
            self.ad.save()

    def __unicode__(self):
        if self.redeemed:
            redeemed = u"Redeemed"
        else:
            redeemed = u"Not redeemed"

        return u"{0} - {1} - {2}".format(self.user.email, self.ad.title, redeemed)

    class Meta:
        ordering = ("-id",)
Run Code Online (Sandbox Code Playgroud)

你有什么想法?

ari*_*rie 5

 user = models.ForeignKey(settings.AUTH_USER_MODEL)
Run Code Online (Sandbox Code Playgroud)

您的模型要求用户设置,但显然不是(不再).

问题是为什么?

查看您的代码,这将成为相关的行:

def pre_save(self, obj):
    obj.user = self.request.user
Run Code Online (Sandbox Code Playgroud)

假设您也升级了DRF,那么这种方法就不再适用了:http://www.django-rest-framework.org/topics/3.0-announcement/#changes-to-prepost-save-hooks

因此,您必须perform_create根据文档中的说明调整代码并使用.