Bogdan Condurache
Bogdan Condurache

Reputation: 445

Send current user when model is saved in Django

I have a problem after a bigger upgrade from Django 1.7 to 1.10 and to Django Rest Framework 3.5.4. The problem is when I try to access the endopint /claims it returns a 500 Error with the text: IntegrityError at /claims (1048, "Column 'user_id' cannot be null")

In urls.py that route is added like this:

url('^claims', v.ClaimList.as_view(), name='claim_list')

And the relevant part from the views.py file is:

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 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)
        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

And the claim model is:

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
        super(Claim, self).save(*args, **kwargs) # here is where it crashes

Do you have any ideas what could cause the problem?

Upvotes: 1

Views: 1789

Answers (1)

arie
arie

Reputation: 18982

 user = models.ForeignKey(settings.AUTH_USER_MODEL)

Your model requires that a user gets set, but obviously it isn't (anymore).

The question is why?

Looking at your code this seens to be the relevant line:

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

Assuming you also upgraded DRF it is quite plausible that this doesn't work anymore: http://www.django-rest-framework.org/topics/3.0-announcement/#changes-to-prepost-save-hooks

So you have to adapt your code and use perform_create as explained in the docs.

Upvotes: 6

Related Questions