Home > front end >  How to display images in Django questionnaire
How to display images in Django questionnaire

Time:11-17

I am working on a Django app where the user will be able to take any survey they pick from a list of surveys. For one of the surveys, they are supposed to select an image that best represents their mood. For their answer I do not need to record the image they selected, just the name of the mood it represents (for example, "cheerful"). Therefore, I have not yet added an "image" field to the model. However, the user should be able to see the image and select it. At the moment I am not able to display the images, only getting the names. I have checked my code and still unable to find the mistake. By the way, not getting any technical error messages. Any recommendations you have are appreciated. Below are my models, views, and HTML. I apologize for the lengthy files.

Thank you!

Models

User = settings.AUTH_USER_MODEL

class Questionnaire(models.Model): 
    name = models.CharField(max_length=255) 
    text = models.CharField(max_length=200)

    def __str__(self):
        return self.name

class Question(models.Model):
    text = models.CharField(max_length=200)
    questionnaire = models.ForeignKey(Questionnaire, on_delete=models.CASCADE, related_name='questions')
    def __str__(self):
        return self.text

class Answer(models.Model):
    questionnaire = models.ForeignKey(Questionnaire, on_delete=models.CASCADE, related_name='answers', default='')
    text = models.CharField(max_length=200)

    def __str__(self):
        return self.text
 
class Response(models.Model):
    user = models.ForeignKey(User, on_delete = models.CASCADE)  
    date = models.DateTimeField(auto_now_add=True)
    question = models.ForeignKey(Question, on_delete = models.CASCADE)
    answer = models.ForeignKey(Answer, on_delete = models.CASCADE)
    def __str__(self):
        return '%s - %s - %s - %s' % (self.user, self.question, self.answer, self.date)

Views

from django.forms import ModelForm
class ResponseForm(ModelForm):
    class Meta:
        model = Response
        fields = ['question', 'answer']
        # widgets= {'answer': RadioSelect}
    
    def __init__(self, *args, user=None, **kwargs):
        self.user = user
        super().__init__(*args, **kwargs)

    def save(self, commit=True):
        response = super().save(commit=False)
        response.user = self.user
        return response.save()


def take_questionnaire_fs(request, questionnaire_id):

    ResponseFormSet = modelformset_factory(Response, form=ResponseForm, extra=0)
    if request.method == 'POST':
        formset = ResponseFormSet(request.POST or None, request.FILES, form_kwargs={'user': request.user})
        if formset.is_valid():
            print("Formset is valid")
            formset.save()
            return HttpResponseRedirect(reverse ('questionnaires:questionnaire_index'))
        else:
            print("Formset is NOT valid")
            print(formset.errors)
            print(formset.non_form_errors())

    questions = Question.objects.filter(questionnaire_id=questionnaire_id)
    answers = Answer.objects.filter(questionnaire_id=questionnaire_id)

    return render(request, 'questionnaires/take_questionnaire_fs.html', {
        'questions': questions,
        'answers': answers,
        })

HTML

{% extends "base.html" %}
{% block page_content %}


{% if questionnaire.name == 'Pick-a-Mood' %}
<form action="{{ request.url }}" method="post">
{% csrf_token %} 
  <style>

    .circle-container {
            position: relative;
            width: 24em;
            height: 24em;
            padding: 2.8em;
            /*2.8em = 2em*1.4 (2em = half the width of a link with img, 1.4 = sqrt(2))*/
            /* border: dashed 1px; */
            border-radius: 50%;
            margin: 1.75em auto 0;
        }
        .circle-container label {
            display: block;
            position: absolute;
            top: 50%; left: 50%;
            width: 8em; height: 8em;
            margin: -2em;
        }
        .circle-container img { display: block; width: 100%; }
        .deg22_5 { transform: rotate(22.5deg) translate(12em) rotate(-22.5deg); }
        .deg67_5 { transform: rotate(67.5deg) translate(12em) rotate(-67.5deg); }
        .deg112_5 { transform: rotate(112.5deg) translate(12em) rotate(-112.5deg); }
        .deg157_5 { transform: rotate(157.5deg) translate(12em) rotate(-157.5deg); }
        .deg202_5 { transform: rotate(202.5deg) translate(12em) rotate(-202.5deg); }
        .deg247_5 { transform: rotate(247.5deg) translate(12em) rotate(-247.5deg); }
        .deg292_5 { transform: rotate(292.5deg) translate(12em) rotate(-292.5deg); }
        .deg337_5 { transform: rotate(337.5deg) translate(12em) rotate(-337.5deg); }
    
    
    /* HIDE RADIO */
    [type=radio] { 
      position: absolute;
      opacity: 0;
      width: 0;
      height: 0;
    }
    
    /* IMAGE STYLES */
    [type=radio]   img {
      cursor: pointer;
    }
    
    /* CHECKED STYLES */
    [type=radio]:checked   img {
      border: 2px solid #f00;
      
    }
    [type=radio]:not(:checked)   img {
      border: none;
    }
    
    </style>

    <div class="circle-container">
        <label class='center'>
            <input type="radio" name="pickamood" value="Neutral">
            <img src="/static/mysurveys/female_neutral.png">
        </label>
    
        <label class='deg22_5'>
            <input type="radio" name="pickamood" value="Relaxed">
            <img src="/static/mysurveys/female_relaxed.png">
        </label>
    
        <label class='deg67_5'>
            <input type="radio" name="pickamood" value="Calm">
            <img src="/static/mysurveys/female_calm.png">
        </label>
    
        <label class='deg112_5'>
            <input type="radio" name="pickamood" value="Bored">
            <img src="/static/mysurveys/female_bored.png">
        </label> 
        
        <label class='deg157_5'>
            <input type="radio" name="pickamood" value="Sad">
            <img src="/static/mysurveys/female_sad.png">
        </label>
    
        <label class='deg202_5'>
            <input type="radio" name="pickamood" value="Irritated">
            <img src="/static/mysurveys/female_irritated.png">
        </label>
    
        <label class='deg247_5'>
            <input type="radio" name="pickamood" value="Tense">
            <img src="/static/mysurveys/female_tense.png">
        </label>
    
        <label class='deg292_5'>
            <input type="radio" name="pickamood" value="Excited">
            <img src="/static/mysurveys/female_excited.png">
        </label>     
    
        <label class='deg337_5'>
            <input type="radio" name="pickamood" value="Cheerful">
            <img src="/static/mysurveys/female_cheerful.png">
        </label>     
    </div>
<a>
  <input type="submit" value="Submit" >
</a>
 
</form>

{% else %}
<form method="post" action="{{ request.url }}">
    {% csrf_token %}

    {% for question in questions %}
        <h1>{{question.text}}</h1> 
    
        <label hidden="" for="id_form-{{ forloop.counter0 }}-question">Question:</label>
        <select hidden="" name="form-{{ forloop.counter0 }}-question" id="id_form-{{ forloop.counter0 }}-question">
            <option value="{{question.id}}" selected="">{{question.text}}</option>
        </select>

        <label for="id_form-{{ forloop.counter0 }}-answer">Answer:</label>
        <select required="" name="form-{{ forloop.counter0 }}-answer" id="id_form-{{ forloop.counter0 }}-answer">
            <option value="" selected="">---------</option>
            {% for answer in answers %}
                <option value="{{answer.id}}">{{answer.text}}</option>
            {% endfor %}
        </select>
        
        <input type="hidden" name="form-{{ forloop.counter0 }}-id" value="{{ forloop.counter }}" id="id_form-{{ forloop.counter0 }}-id">
           
        <input type="hidden" name="form-TOTAL_FORMS" value="{{questions|length}}" id="id_form-TOTAL_FORMS" />
        <input type="hidden" name="form-INITIAL_FORMS" value="0" id="id_form-INITIAL_FORMS" />
        <input type="hidden" name="form-MAX_NUM_FORMS" value="{{questions|length}}" id="id_form-MAX_NUM_FORMS" />

    {% endfor %}


    <br />
    <br />
    <input type="submit" value="Submit">
</form>
{% endif %}

{% endblock %}

CodePudding user response:

You need to use static files.

Make sure it’s set up in your settings.py and then in the html load static and use it to get your files.

Eg. Assuming your files are in a static folder and that is set up in settings.py

<img src="{% static 'mysurveys/female_irritated.png' %}">

CodePudding user response:

Try these steps in order:

  1. Make sure that django.contrib.staticfiles is included in your INSTALLED_APPS.

  2. In your settings file, define STATIC_URL:

     STATIC_URL = '/static/'
    
  3. In your template file

     {% load static %}
     <img src="{% static 'mysurveys/female_irritated.png' %}" alt="image alt">
    
  4. Store your static files in a folder called static in your app. For example my_app/static/mysurveys/female_bored.png. As you done already

More informations in Django doc.

  • Related