Closed sphrlbd closed 6 months ago
To successfully utilize two GalleryField instances within a single Django model, it's essential to first establish two distinct ImageModel classes. Here's a step-by-step guide using an example app named my_app:
Create two separate models for the images, each with its ImageField. This ensures each GalleryField can reference its specific image model. Crucially, include the get_image_field class method to specify the image field to be used.
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.conf import settings
from django.utils.timezone import now
from galleryfield.models import GalleryField
from django.core.files.storage import default_storage
class MyImage1(models.Model):
photo1 = models.ImageField(
upload_to="my_images1", storage=default_storage, verbose_name=_("Image1"))
creator = models.ForeignKey(
settings.AUTH_USER_MODEL, null=False, blank=False,
verbose_name=_('Creator'), on_delete=models.CASCADE)
creation_time = models.DateTimeField(default=now(), blank=False)
@classmethod
def get_image_field(cls):
return cls._meta.get_field("photo1")
class MyImage2(models.Model):
photo2 = models.ImageField(
upload_to="my_images2", storage=default_storage, verbose_name=_("Image2"))
@classmethod
def get_image_field(cls):
return cls._meta.get_field("photo2")
MyImage1 Model: Configures photo1 with upload_to path my_images1.
MyImage2 Model: Configures photo2 with upload_to path my_images2.
Both models should implement the get_image_field
method to return their respective image fields. This method is key for the GalleryField
to identify the correct image field within the model.
In your gallery model, incorporate the two GalleryField instances. Each should reference one of the image models you've defined (MyImage1 and MyImage2). This setup allows each GalleryField to manage a separate set of images.
class MyGallery(models.Model):
album1 = GalleryField(target_model="my_app.MyImage1", verbose_name=_('My photos'))
album2 = GalleryField(target_model="my_app.MyImage2", verbose_name=_('My photos2'))
owner = models.ForeignKey(
settings.AUTH_USER_MODEL, null=False, blank=False,
verbose_name=_('Owner'), on_delete=models.CASCADE)
Thanks. should i configure anything else like urls?
should i configure anything else like urls?
urls for what? I you only need to render the images, no need to configure urls.
should i configure anything else like urls?
urls for what? I you only need to render the images, no need to configure urls.
Because it says:
'upload_url' is invalid: 'ImproperlyConfigured': ''event-myimage1-upload' is invalid: 'NoReverseMatch': 'Reverse for 'event-myimage1-upload' not found. 'event-myimage1-upload' is not a valid view function or pattern name.
and after i manually configure the urls both of images will be uploaded to the MyImage2
Can I have a better way to contact to you? I really need this for my project asap. Thanks☺️ @dzhuang
Sorry for my late response, I'm buried with works. Can you look into the demo_custom
app in the repo which is the custom version of how to use the package.
Yes i wrote everything like your demo but both of the images will be uploaded to the model 2 and i don't know why Thanks anyway.
Can you paste the code here?
Sure
image_views.py:
from django.core.exceptions import PermissionDenied
from galleryfield.image_views import ImageCreateView, ImageListView, ImageCropView
class MyImage1CreateView(ImageCreateView):
target_model = "event.MyImage1"
disable_server_side_crop = False
def create_instance_from_form(self, form):
self.object = form.save(commit=False)
self.object.creator = self.request.user
self.object.save()
class MyImage1ListView(ImageListView):
target_model = "event.MyImage1"
disable_server_side_crop = False
def get_queryset(self):
queryset = super().get_queryset()
if not self.request.user.is_superuser:
queryset = queryset.filter(creator=self.request.user)
return queryset
class MyImage1CropView(ImageCropView):
target_model = "event.MyImage1"
disable_server_side_crop = False
def get_object(self, queryset=None):
obj = super().get_object(queryset=None)
if not self.request.user.is_superuser and obj.creator != self.request.user:
raise PermissionDenied("May not crop other user's image")
return obj
def create_cropped_instance_from_form(self, form):
# we don't need to set self.object.creator here because
# it's copied from the original instance.
self.object = form.save()
class MyImage2CreateView(ImageCreateView):
target_model = "event.MyImage2"
disable_server_side_crop = False
def create_instance_from_form(self, form):
self.object = form.save(commit=False)
self.object.creator = self.request.user
self.object.save()
class MyImage2ListView(ImageListView):
target_model = "event.MyImage2"
disable_server_side_crop = False
def get_queryset(self):
queryset = super().get_queryset()
if not self.request.user.is_superuser:
queryset = queryset.filter(creator=self.request.user)
return queryset
class MyImage2CropView(ImageCropView):
target_model = "event.MyImage2"
disable_server_side_crop = False
def get_object(self, queryset=None):
obj = super().get_object(queryset=None)
if not self.request.user.is_superuser and obj.creator != self.request.user:
raise PermissionDenied("May not crop other user's image")
return obj
def create_cropped_instance_from_form(self, form):
# we don't need to set self.object.creator here because
# it's copied from the original instance.
self.object = form.save()
urls.py:
from django.urls import path
from event import image_views
urlpatterns = [
path(
"upload1/",
image_views.MyImage1CreateView.as_view(),
name="event-myimage1-upload",
),
path(
"fetch1/",
(image_views.MyImage1ListView.as_view()),
name="event-myimage1-fetch",
),
path(
"crop1/<int:pk>",
image_views.MyImage1CropView.as_view(),
name="event-myimage1-crop",
),
path(
"upload2/",
image_views.MyImage2CreateView.as_view(),
name="event-myimage2-upload",
),
path(
"fetch2/",
(image_views.MyImage2ListView.as_view()),
name="event-myimage2-fetch",
),
path(
"crop2/<int:pk>",
image_views.MyImage2CropView.as_view(),
name="event-myimage2-crop",
),
]
models.py:
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.conf import settings
from django.utils.timezone import now
from galleryfield.fields import GalleryField
from django.core.files.storage import default_storage
from PIL import Image
def fileName(image):
file_url = list(image.url.split("/"))
file_url.reverse()
file_name = file_url[0].split(".")[0]
return file_name
class MyImage1(models.Model):
photo1 = models.ImageField(
upload_to="my_images1", storage=default_storage, verbose_name=_("Image1")
)
creator = models.ForeignKey(
settings.AUTH_USER_MODEL,
null=False,
blank=False,
verbose_name=_("Creator"),
on_delete=models.CASCADE,
)
@classmethod
def get_image_field(cls):
return cls._meta.get_field("photo1")
class MyImage2(models.Model):
photo2 = models.ImageField(
upload_to="my_images2", storage=default_storage, verbose_name=_("Image2")
)
@classmethod
def get_image_field(cls):
return cls._meta.get_field("photo2")
class MyGallery(models.Model):
album1 = GalleryField(target_model="event.MyImage1", verbose_name=_("My photos"))
album2 = GalleryField(target_model="event.MyImage2", verbose_name=_("My photos2"))
owner = models.ForeignKey(
settings.AUTH_USER_MODEL,
null=False,
blank=False,
verbose_name=_("Owner"),
on_delete=models.CASCADE,
)
I see. I'll try your code in a few days.
@sphrlbd Can you add more code in #62 ? Thanks
I can reproduce what you've described. Labeled bug
. I need sometime to figure out the workround. Thanks for reporting.
The issue should be here
potential duplicated css selectro of fileinputs, and here:
there should be no each
because the rendered widget should have a unique name
or id
.
Thanks a lot What exactly should i do to fix that?
Now it's fixed by #63 and I'm closing this issue.
Hi, how can I use two gallery field in one model when I do that, all the files will be uploaded in one filed