我有两个型号,房间和图像. Image是一个可以应用于任何其他模型的通用模型.我想为用户提供一个表单,用于在发布有关房间的信息时上传图像.我已经编写了有效的代码,但我担心我已经做到了这一点,特别是以违反DRY的方式.
希望对django形式更熟悉的人可以指出我出错的地方.
更新:
我试图澄清为什么我在评论中选择这个设计来解答当前的答案.总结一下:
我没有简单地将ImageField放在Room模型上,因为我想要一个与Room模型相关联的多个图像.我选择了一个通用的Image模型,因为我想将图像添加到几个不同的模型中.我考虑的替代方案是单个Image类上的多个外键,这看起来很乱,或者是多个Image类,我认为这会使我的模式混乱.我在第一篇文章中没有说清楚,对此感到抱歉.
看到目前为止没有任何答案已经解决了如何使这更干一点干我确实提出了我自己的解决方案,即在图像模型上添加上传路径作为类属性,并在每次需要时引用它.
# Models
class Image(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
image = models.ImageField(_('Image'),
height_field='',
width_field='',
upload_to='uploads/images',
max_length=200)
class Room(models.Model):
name = models.CharField(max_length=50)
image_set = generic.GenericRelation('Image')
# The form
class AddRoomForm(forms.ModelForm):
image_1 = forms.ImageField()
class Meta:
model = Room
# The view
def handle_uploaded_file(f):
# DRY violation, I've already specified the upload path in the image model
upload_suffix = join('uploads/images', f.name)
upload_path = join(settings.MEDIA_ROOT, upload_suffix)
destination = open(upload_path, 'wb+')
for chunk in f.chunks():
destination.write(chunk)
destination.close()
return upload_suffix
def add_room(request, apartment_id, form_class=AddRoomForm, template='apartments/add_room.html'):
apartment = Apartment.objects.get(id=apartment_id)
if request.method == 'POST':
form = form_class(request.POST, request.FILES)
if form.is_valid():
room = form.save()
image_1 = form.cleaned_data['image_1']
# Instead of writing a special function to handle the image,
# shouldn't I just be able to pass it straight into Image.objects.create
# ...but it doesn't seem to work for some reason, wrong syntax perhaps?
upload_path = handle_uploaded_file(image_1)
image = Image.objects.create(content_object=room, image=upload_path)
return HttpResponseRedirect(room.get_absolute_url())
else:
form = form_class()
context = {'form': form, }
return direct_to_template(request, template, extra_context=context)
解决方法:
您不必使用Image类.如DZPM所示,将图像字段转换为ImageField.您还需要对视图进行一些更改.
您可以使用上载的数据创建Image对象,并将Image对象附加到Room对象,而不是使用上传处理程序.
要保存Image对象,您需要在视图中执行以下操作:
from django.core.files.base import ContentFile
if request.FILES.has_key('image_1'):
image_obj = Image()
image_obj.file.save(request.FILES['image_1'].name,\
ContentFile(request.FILES['image_1'].read()))
image_obj.save()
room_obj.image_set.create(image_obj)
room_obj.save()
此外,我认为不应使用GenericRelation,而应使用ManyToManyField,在这种情况下,将图像添加到房间的语法会略有变化.
标签:python,django,django-forms 来源: https://codeday.me/bug/20190827/1743996.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。