Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
103 views
in Technique[技术] by (71.8m points)

html - Rendering images in Django ModelForm instead of __str__ representation

I have the following django models / forms / views / html setup. So I am rendering the InputFileForm in the html and the user should select from dropdown list a face_file that is saved in the Face model (preloaded via fixtures). I would like to have the face_file images to be rendered in the dropdown (alternatively a radio select would be fine as well) instead of the image str names - as it currently looks like the following:

Image of current dropdown

So in short: I would like to have an image rendered in the dropdown instead of the "Face 1", "Face 2",...

Thanks in advance for your help!

class Face(models.Model):
    face_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=64)
    face_file = models.ImageField(upload_to='../media/faces', blank=True, null=True)

    def __str__(self):
        return self.name

class InputFile(models.Model):
    input_id = models.AutoField(primary_key=True)
    input_flatlay_file = models.ImageField(upload_to='../media/flatlays', blank=True, null=True)
    input_face_file = models.ForeignKey(Face, null=True, blank=True, on_delete=models.CASCADE, related_name="inputs_using_this_face")
    input_user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.CASCADE, related_name="user_inputs")



class Prediction(models.Model):
    prediction_id = models.AutoField(primary_key=True)
    prediction_inputs = models.ForeignKey(InputFile, null=True, blank=True, on_delete=models.CASCADE, related_name="prediction_inputs")
    output_lookbook_file = models.ImageField(upload_to='../media/lookbooks', blank=True, null=True)
    prediction_user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.CASCADE, related_name="user_predictions")



I have a ModelForm for InputFile:

class MyModelChoiceField(ModelChoiceField):
    def label_from_instance(self, obj):
        return mark_safe('<img src="%s">' %obj.face_file.url)


class InputFileForm(forms.ModelForm): 
    class Meta: 
        model = InputFile 
        fields = ['input_flatlay_file','input_face_file']
        widgets = {
                    'input_face_file': MyModelChoiceField(queryset=Face.objects.all()),
                }

In my views.py:

def prediction(request):
    form=forms.InputFileForm()
    
    if request.method == 'POST':
        form = forms.InputFileForm(request.POST or None, request.FILES or None) 
        if form.is_valid():
            new_input = form.save(commit=False)
            new_input.input_user = request.user
            new_input.save()
            output_lookbook_file = util.prediction(new_input.input_flatlay_file, new_input.input_face_file.face_file)
            new_prediction = Prediction(output_lookbook_file = output_lookbook_file, prediction_user = request.user, prediction_inputs=new_input)
            new_prediction.save()
            return render(request, "modelgan/prediction.html", {"form": form, 
                                "new_input":new_input, "new_prediction": new_prediction })

        else:
            return render(request, "modelgan/prediction.html", {"form": form })

    return render(request, "modelgan/prediction.html", {"form": form })

In my html I am rendering the ModelForm as following:

    {% if user.is_authenticated %}

    <form action="{% url 'prediction' %}" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <form action="" method="POST">
  
            {% csrf_token %}
            {{ form.as_table  }}

            <input type="submit" value="Generate lookbook image">
        </form>
    </form>
question from:https://stackoverflow.com/questions/65870673/rendering-images-in-django-modelform-instead-of-str-representation

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can override label_from_instance - see ModelChoiceField.iterator

See also Overriding the default fields

And than you can do something like following:

from django.utils.safestring import mark_safe
from django.forms import ModelChoiceField

class MyModelChoiceField(ModelChoiceField):

    def label_from_instance(self, obj):
        return mark_safe('<img width="60" src="%s">' % obj.face_file.url)


class InputFileForm(forms.ModelForm):

    input_face_file = MyModelChoiceField(
        queryset=Face.objects.all(), required=False, 
        widget=forms.RadioSelect)

    class Meta: 
        model = InputFile 
        fields = ['input_flatlay_file','input_face_file']

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...