I have two models: Room
and Image
. Image
is a general model that can be applied to any other model. I want to provide users with an image upload form when they publish room information. I wrote code that works, but I'm afraid that I did it with great difficulty, and in particular, in such a way that it violates DRY.
Hopefully someone who is a little familiar with the forms of django can indicate where I made a mistake.
Update:
I tried to find out why I chose this project in the comments to the current answers. Summarizing:
I didn’t just fit ImageField
into the model Room
because I need more than one image associated with the room model. I chose the general Image model because I wanted to add images to several different models. The alternatives that I considered were several foreign keys in one class Image
that seemed confusing, or several classes Image
that I thought would clutter up my scheme. I did not clarify this in my first post, so I'm sorry about that.
Seeing that none of the answers so far has discussed how to do this a little more DRY, I really came up with my own solution, which was to add the load path as a class attribute to the image model and a link, whenever necessary.
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')
class AddRoomForm(forms.ModelForm):
image_1 = forms.ImageField()
class Meta:
model = Room
def handle_uploaded_file(f):
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']
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)