将非表单元素注入动态Django表单?

时间:2015-11-23 13:34:08

标签: django django-models django-forms django-templates

是否可以将非表单元素注入动态Django表单的上下文中?我有一个“删除用户照片”表单,我希望包含每个用户的缩略图,其中包含BooleanField复选框和标签正下方:

+------------+
|            |
|   photo    |
|            |
+------------+
[x]  Delete <username>'s photos

现在我知道如何创建动态复选框及其标签,但我不知道如何添加每个用户的照片。从下面的代码中可以看出,每个HTML输入标记的name属性将包含用户的ID,当用户提交表单以确定是否删除他们的照片时,我将检查此属性。我想在每个输入标记上方插入一个链接到用户个人资料照片的标记。图像标记的“src”属性将包含用户的ID,用于创建指向其照片的链接。有没有办法将此非形式图像标记“注入”此动态表单的上下文,以便在每个复选框输入标记的正上方呈现图像标记?

感谢。

# views.py
def remove_access_to_private_photos(request, template):
    if request.method == 'POST':
        form = RemovePrivatePhotoAccessForm(request.POST, this_user_id=request.user.id)
        if form.is_valid():
            for name, value in form.cleaned_data.items():
                if value == True:
                    # Profile links to User via a OneToOneField
                    this_user = Profile.objects.get(user_id=request.user.id)
                    other_user = Profile.objects.get(user_id=name)
                    this_user.remove_private_access(other_user_prof)
        return redirect('photos-home')
    else:
        form = RemovePrivatePhotoAccessForm(this_user_id=request.user.id)
    context = {'form': form}
    return render(request, template, context)

# models.py
class RemovePrivatePhotoAccessForm(forms.Form):
    def __init__(self, *args, **kwargs):
        this_user_id = kwargs.pop('this_user_id')
        super(RemovePrivatePhotoAccessForm, self).__init__(*args, **kwargs)
        user = User.objects.get(pk=this_user_id)
        user_prof = Profile.objects.get(user=user)
        other_user_id_list = user_prof.gave_private_access().values_list('user_id', flat=True)
        for id in other_user_id_list:
            other_user = User.objects.get(pk=id)
            self.fields[str(id)] = forms.BooleanField(required=False)
            self.fields[str(id)].label = mark_safe('<a href="/photos/delete/%s/%s">%s</a>') % (id, this_user_id, other_user.username)

# delete_photos.html
<form action="." method="post">
    {% csrf_token %}

    {% for field in form %}

        {# I'D LIKE TO PUT <IMG> TAG HERE #}
        {{ field }} Delete {{ field.label|safe }}'s photos

    {% endfor %}

    <input type="submit" value="Submit" />
</form>

1 个答案:

答案 0 :(得分:0)

以下是我解决这个问题的方法。首先,我创建了一个自定义模板标记:

    # photos/templatetags/photos_extras.py
    from django import template
    from django.contrib.auth.models import User
    from django.utils.safestring import mark_safe

    register = template.Library()

    @register.simple_tag
    def render_image(uid):
        user = User.objects.get(pk=uid)
        src_string = ''.join([
            '/photos/',
            user.username, '_',
            user.profile.image_id,
            '_thumb.jpg'])
        img_tag = ''.join([
            '<img src="',
            src_string,
            '" alt="',
            user.username,
            '" />'])
        return mark_safe(img_tag)

然后我将自定义模板标记插入到我的模板中。 field.name包含所需用户的用户ID,render_image返回所需的HTML img标记。

# delete_photos.html
<form action="." method="post">
    {% csrf_token %}

    {% for field in form %}

        {% render_image field.name %}
        {{ field }} Delete {{ field.label|safe }}'s photos

    {% endfor %}

    <input type="submit" value="Submit" />
</form>