Adding a common image field to ModelForm in django

I have two models: Roomand Image. Imageis 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 ImageFieldinto the model Roombecause 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 Imagethat seemed confusing, or several classes Imagethat 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.

# 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)
+3
7

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, .

+2

ImageField? Image.

# model
class Room(models.Model):
    name = models.CharField(max_length=50)
    image = models.ImageField(upload_to="uploads/images/")

# form
from django import forms

class UploadFileForm(forms.Form):
    name = forms.CharField(max_length=50)
    image  = forms.FileField()

?

+4

: ?

.

0

Django :

  • formsets .
  • .

changeet [8279]. . , , .

.

, , instance=. , . .

0

.

- , .

: , , ,

, Review, Manufacturer, Profile Image. . ( , One Review 5 , Review 3 ..)

images = ManyToManyField(Image)

. , ( ). . , .

, , - .

class Image(models.Model):
    description = models.TextField(blank=True)
    image = models.ImageField(upload_to="media/")
    user_profile = models.ForeignKey(UserProfile)
    mfgr = models.ForeignKey(Manufacturer)
    review = models.ForeignKey(Review)

, . , .

, , ( , Generic Relationships ( Generic Foreign Keys), . , . .

http://www.djangoproject.com/documentation/models/generic_relations/

, , . !

, .

0

, ... , , , .

GenericForeignKeys .

models.py

from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class Image(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey()

, . , .

images = generic.GenericRelation(Image)

admin.py .

from django.contrib.contenttypes.generic import GenericTabularInline

class ImageInline(GenericTabularInline):
    model = Image
    extra = 3
    ct_field_name = 'content_type'
    id_field_name = 'object_id'

class ReviewAdmin(admin.ModelAdmin):
    inlines = [ImageInline]

. . , ! .adam.

0

: :

class Image (models.Model)

content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
image = models.ImageField(upload_to='')

UploadImage (forms.ModelForm):

class Meta:
    model = Image
    fields = ('image')

Room (models.Model):

name = models.CharField(max_length=50)
images = models.ManyToManyField(Image) 

class RoomForm (forms.ModelForm):

class Meta:
    model = Room

request.method == "POST":

    ##2 form, una per l'annuncio ed una per la fotografia
    form = RoomForm(request.POST)
    image_form = UploadImage(request.POST, request.FILES)
    #my_logger.debug('form.is_valid() : ' + str(form.is_valid()))
    if form.is_valid() and image_form.is_valid():
        ##save room
        room = room.save()

        ##save image
        image = image_form.save()

        ##ManyToMany
        room.images = [image]
        room.save()
0

All Articles