将非表单元素注入动态 Django 表单?
Inject non-form element into dynamic Django form?
是否可以将非表单元素注入到动态 Django 表单的上下文中?我有一个 "Delete user photos" 表单,我想在其中包含每个用户的缩略图,并在其下方带有 BooleanField 复选框和标签:
+------------+
| |
| photo |
| |
+------------+
[x] Delete <username>'s photos
现在我知道如何创建动态复选框及其标签,但我不确定如何添加每个用户的照片。从我下面的代码可以看出,每个 HTML 输入标签的名称属性将包含用户的 ID,我将在用户提交表单时检查此属性以确定是否删除他们的照片。我想在 link 到用户个人资料照片的每个输入标签上方插入一个标签。图片标签的 "src" 属性将包含用户的 ID,该 ID 为他们的照片创建 link。有没有办法 "inject" 这个非表单图像标签进入这个动态表单的上下文,以便在每个复选框输入标签的正上方呈现图像标签?
谢谢。
# 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>
表单字段只是一个 class,因此您可以在实例化时或实例化后添加所需的任何属性。鉴于此示例代码,您的观点保持不变。
# forms.py
from .models import Profile # or whatever
class RemovePrivatePhotoAccessForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
user_id = kwargs.pop('user_id')
user_profile = Profile.objects.get(pk=user_id)
other_profiles = user_profile.gave_private_access()
for profile in other_profiles:
id = str(profile.id)
field = forms.BooleanField(required=False)
field.label = mark_safe('<a href="/photos/delete/%s/%s">%s</a>') % (id, user_profile.id, profile.username)
field.photo = profile.photo
self.fields[id] = field
super(RemovePrivatePhotoAccessForm, self).__init__(*args, **kwargs)
# delete_photos.html
<form action="." method="post">
{% csrf_token %}
{% for field in form %}
<img src="{{ field.photo.url }}" />
{{ field }} Delete {{ field.label|safe }}'s photos
{% endfor %}
<input type="submit" value="Submit" />
</form>
这是我解决这个问题的方法。首先我创建了一个自定义模板标签:
# 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 returns 包含所需的 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>
是否可以将非表单元素注入到动态 Django 表单的上下文中?我有一个 "Delete user photos" 表单,我想在其中包含每个用户的缩略图,并在其下方带有 BooleanField 复选框和标签:
+------------+
| |
| photo |
| |
+------------+
[x] Delete <username>'s photos
现在我知道如何创建动态复选框及其标签,但我不确定如何添加每个用户的照片。从我下面的代码可以看出,每个 HTML 输入标签的名称属性将包含用户的 ID,我将在用户提交表单时检查此属性以确定是否删除他们的照片。我想在 link 到用户个人资料照片的每个输入标签上方插入一个标签。图片标签的 "src" 属性将包含用户的 ID,该 ID 为他们的照片创建 link。有没有办法 "inject" 这个非表单图像标签进入这个动态表单的上下文,以便在每个复选框输入标签的正上方呈现图像标签?
谢谢。
# 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>
表单字段只是一个 class,因此您可以在实例化时或实例化后添加所需的任何属性。鉴于此示例代码,您的观点保持不变。
# forms.py
from .models import Profile # or whatever
class RemovePrivatePhotoAccessForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
user_id = kwargs.pop('user_id')
user_profile = Profile.objects.get(pk=user_id)
other_profiles = user_profile.gave_private_access()
for profile in other_profiles:
id = str(profile.id)
field = forms.BooleanField(required=False)
field.label = mark_safe('<a href="/photos/delete/%s/%s">%s</a>') % (id, user_profile.id, profile.username)
field.photo = profile.photo
self.fields[id] = field
super(RemovePrivatePhotoAccessForm, self).__init__(*args, **kwargs)
# delete_photos.html
<form action="." method="post">
{% csrf_token %}
{% for field in form %}
<img src="{{ field.photo.url }}" />
{{ field }} Delete {{ field.label|safe }}'s photos
{% endfor %}
<input type="submit" value="Submit" />
</form>
这是我解决这个问题的方法。首先我创建了一个自定义模板标签:
# 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 returns 包含所需的 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>