yestema
yestema

Reputation: 8112

django rest framework, Additional checks and saves in ViewSet and return different response depends on condition

I'm making voting. All user can vote 1 time in 24 hours. User making vote with POST request. Every time he vote I want to check the last time he voted:

UPDATE. There were just stupid syntax error in my code — that's not interesting to anybody. So I delete my wrong code and left this post Just for the main question.

Upvotes: -1

Views: 266

Answers (3)

yestema
yestema

Reputation: 8112

UPDATE: I finally solve this problem. There was a lot of syntax errors Update code to correct version. May be somebody will need it so I've put it here: But there is the better solution below from Bear Brown

views.py:

class VoteAddViewSet(viewsets.ModelViewSet):
    queryset = Vote.objects.all()
    serializer_class = VoteAddSerializer
    http_method_names = ['post',]

    def perform_create(self, serializer):
        profile = Profile.objects.get(pk=self.request.user.id)
        allow_vote_date = profile.vote_date + timedelta(days=1)
        if (allow_vote_date < timezone.now()):
            profile.vote_date = timezone.now()
            profile.save()
            serializer.save(user=self.request.user)
        else:
            return Response(status=status.HTTP_400_BAD_REQUEST)

serializers.py:

class VoteAddSerializer(serializers.ModelSerializer):
class Meta:
    model = Vote
    exclude =('id','created_date','user',)

urls.py:

router = routers.DefaultRouter()
router.register(r'vote_add', views.VoteAddViewSet, 'vote_add')
urlpatterns = [ url(r'^', include(router.urls)),]

models.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
    vote_date = models.DateTimeField(default=None, null=True, blank=True)

class Girl (models.Model):
    user = models.OneToOneField(User, null=True, blank=True, on_delete=models.SET_NULL)
    title = models.CharField(max_length=120, null=True, blank=True)
    pic =  models.ImageField(upload_to='girls/pic1/', blank=True, default=None)

class Vote (models.Model):
    user = models.ForeignKey(User, null=True, blank=True, related_name='girls_user_voted_for', on_delete=models.SET_NULL)
    girl = models.ForeignKey(Girl, null=True, blank=True, related_name='supporters_of_this_girl', on_delete=models.SET_NULL)
    created_date = models.DateTimeField(default=timezone.now)
    def __unicode__(self):
        return u'{}'.format(self.id)

Upvotes: 0

user8060120
user8060120

Reputation:

i think you better to use object-level-validation

class VoteAddSerializer(serializers.ModelSerializer):
    class Meta:
        model = Vote
        exclude =('id','created_date','user',)

    def validate(self, data):
        request = self.context.get('request')
        vote_date = request.user.profile.vote_date
        if vote_date + timedelta(days=1) > timezone.now():
            raise serializers.ValidationError("You need wait to vote again")
        return data

Upvotes: 2

John Moutafis
John Moutafis

Reputation: 23134

You have curly brackets ({}) after your if statement in perform_create. Remove those because they are not used in Python to mark the boundaries of a statement/function etc.

Upvotes: 1

Related Questions