0

models.py

class Survey_Answer(models.Model):
    
    CHOICES = [('Disagree Strongly', 'Disagree Strongly'),
            ('Disagree', 'Disagree'),
            ('Undecided', 'Undecided'),
            ('Agree', 'Agree'),
            ('Agree Strongly', 'Agree Strongly')]
    
    question = models.ForeignKey(Survey_Question, on_delete=models.CASCADE)
    answer_text = models.CharField(max_length=20, choices=CHOICES, default='Undecided')
    date_published = models.DateTimeField('date published', auto_now_add=True)
    created_at = models.DateTimeField('created at', auto_now_add=True)

    
    def __str__(self):
        return self.answer_text + ' -  ' + self.question.question_text

This is my models.py. I need help in assigning value for a particular option in CHOICES( Eg: 5 points for Agree Strongly option). If a user selects an option from choices, he should be getting points based on the option he selected

Roronoa_Z
  • 11
  • 2
  • 1
    It's not clear what you are trying to achieve, please explain in more detail. – Jacques Gaudin Jun 21 '22 at 09:49
  • You can use tuples as choices. – Manoj Kamble Jun 21 '22 at 10:07
  • @JacquesGaudin Sure...For Example, if a user selects "Agree Strongly" he should be getting a value of 5 points when selecting that option and on a scale of 5 to 1 point if he selects Disagree Strongly he should be getting 1 point – Roronoa_Z Jun 21 '22 at 10:37
  • What are these points? Where are they stored? At which point are they awarded? – Jacques Gaudin Jun 21 '22 at 10:39
  • They are awarded based on the options in CHOICES...I am engaged in a survey project and there will be a list of questions where each option holds a certain value...If a user selects Agree in CHOICES he should be assigned a value of 3...I am using Django for the backend So need to give validation for these options in the backend – Roronoa_Z Jun 21 '22 at 11:00

3 Answers3

0

If you want to use choices, you can use them as tuples.

CHOICES = (('Disagree Strongly', 'Disagree Strongly'),
        ('Disagree', 'Disagree'),
        ('Undecided', 'Undecided'),
        ('Agree', 'Agree'),
        ('Agree Strongly', 'Agree Strongly'))

Insted of [] use ().

Manoj Kamble
  • 620
  • 1
  • 4
  • 21
  • Hi @ManojKamble Thanks for the suggestion but I need help in assigning values for those choices – Roronoa_Z Jun 21 '22 at 10:11
  • 1
    Can you explain in more details? – Manoj Kamble Jun 21 '22 at 10:14
  • Sure..For Example, if a user selects "Agree Strongly" he should be getting a value of 5 points when selecting that option and on a scale of 5 to 1 point if he selects Disagree Strongly he should be getting 1 point – Roronoa_Z Jun 21 '22 at 10:29
0

you can override the save method of the model.

class Survey_Answer(models.Model):

 def save(self,*args, **kwargs):
 **Do Stuff whatever you want** //Give points to users
 super(Survey_Answer, self).save(*args, **kwargs)
Manoj Kamble
  • 620
  • 1
  • 4
  • 21
0

There are two way to achieve this. Either use choices tuple with your desired value or override save method of the model.

1ST OPTION:

class Survey_Answer(models.Model):
    
    CHOICES = (('Disagree Strongly', '1'),
            ('Disagree', '2'),
            ('Undecided', '3'),
            ('Agree', '4'),
            ('Agree Strongly', '5'))
    
    question = models.ForeignKey(Survey_Question, on_delete=models.CASCADE)
    answer_text = models.CharField(max_length=20, choices=CHOICES, default='Undecided')
    date_published = models.DateTimeField('date published', auto_now_add=True)
    created_at = models.DateTimeField('created at', auto_now_add=True)

    
    def __str__(self):
        return self.answer_text + ' -  ' + self.question.question_text

It simply means user will select the left option(1st element of the tuple) and you can use the right option(2nd element of the tuple) for your processing. So if user selects 'Agree Strongly' you will have '5' value as well. You can then use serializers to show that value. The syntax for using this will be get_your_field_display.

serializers.py file

from rest_framework import serializers

class SurveySerializer(serializers.ModelSerializer):
    value = serializers.Charfield(source = 'get_answer_text_display', read_only = True)

    class Meta:
        model = Survey_Answer
        fields = ('question', 'answer_text', 'date_published', 'value') # assuming that you don't want users to see created at field

please note that value is a custom field in the serializer.

2ND OPTION:

2nd and preferred option would be to add another field in your model and override save method to add this value

models.py

class Survey_Answer(models.Model):
    
    CHOICES = (('Disagree Strongly', '1'),
            ('Disagree', '2'),
            ('Undecided', '3'),
            ('Agree', '4'),
            ('Agree Strongly', '5'))
    
    question = models.ForeignKey(Survey_Question, on_delete=models.CASCADE)
    answer_text = models.CharField(max_length=20, choices=CHOICES, default='Undecided')
    date_published = models.DateTimeField('date published', auto_now_add=True)
    created_at = models.DateTimeField('created at', auto_now_add=True)
    value = models.IntegerField()


    def save(self,*args, **kwargs):
        self.value = # add your value based based on if else or above trick used in serializers
        super(Survey_Answer, self).save(*args, **kwargs)
    
    def __str__(self):
        return self.answer_text + ' -  ' + self.question.question_text
Moheb
  • 138
  • 1
  • 6