Поле загрузки нескольких изображений в Django - PullRequest
0 голосов
/ 18 февраля 2020

Я новичок в Django и использую этот учебник , чтобы добавить поле загрузки нескольких изображений в модель в моем веб-приложении. Пока я застрял (я не могу связать загруженные фотографии с моделью отеля. Фотографии загружаются, но не связаны с моделью отеля) о том, как связать мою фотомодель с отелями. Модель в HotelCreateView. Мой вопрос заключается в том, как мне связать это несколько изображений, поданных с моей моделью отеля, чтобы при создании отеля загруженные изображения были связаны с созданным отелем. Любезно помочь.

Большое спасибо

Модель отеля

class Hotels(models.Model):
    """Stores all the information about the hotel and also used to query hotels"""

    name = models.CharField(max_length=255) #The name of the hotel
    address = models.CharField(max_length=255)
    city = models.CharField(max_length=255)
    country = models.CharField(max_length=255)
    mobile_number = models.CharField(max_length=12)
    created_at = models.DateTimeField(default=timezone.now)
    last_modified = models.DateTimeField(auto_now=True)
    description = models.TextField()
    slug = models.SlugField(unique=True)
    property_photo = models.ImageField(default='default.jpg', upload_to='hotel_photos')
    star_rating = models.PositiveIntegerField()
    contact_person = models.ForeignKey(UserProfile, on_delete=models.SET_NULL, null=True, blank=True,) #Owner of the hotel or person who created the hotel

    class Meta:
        unique_together = ('name', 'slug')
        verbose_name_plural = 'Hotels'  

Фотомодель

class Photo(models.Model):
    title = models.CharField(max_length=255, blank=True)
    file = models.ImageField(upload_to='hotel_photos')
    hotel = models.ForeignKey(Hotels,on_delete=models.SET_NULL, null=True, blank=True,)

    class Meta:
        verbose_name_plural = 'Photos'


    def __str__(self):
        """Prints the name of the Photo"""
        return f'{self.hotel} photos'

Forms.py

class PhotoForm(forms.ModelForm):
    class Meta:
        model = Photo
        fields = ('hotel','file', )

Views.py

class PhotoUploadView(LoginRequiredMixin,View):
    def get(self, request):
        photos_list = Photo.objects.all()
        return render(self.request, 'hotels/uploads.html', {'photos': photos_list})

    def post(self, request):
        form = PhotoForm(self.request.POST, self.request.FILES, self.request.user)
        if form.is_valid():
            photo = form.save(commit=False)
            photo.hotel = self.request.hotel.contact_person
            photo.save()
            data = {'is_valid': True, 'name': photo.file.name, 'url': photo.file.url}
        else:
            data = {'is_valid': False}
        return JsonResponse(data)

Ответы [ 2 ]

0 голосов
/ 18 февраля 2020

Вы говорите, что виджет, позволяющий загружать фотографии, находится на странице создания отеля. Это проблема, потому что это означает, что отель еще не создан, когда загружаются фотографии. Таким образом, загруженные фотографии не будут иметь hotel, с которым они могут быть связаны.

Существует два варианта:

  • Переместите шаг для загрузки фотографий на второй шаг, после гостиница была создана. Добавьте идентификатор отеля, который был только что создан, к URL, который вы вызываете для PhotoUploadView, чтобы он передавался как kwarg для представления.
    # in PhotoUploadView, post()
    if form.is_valid():
        photo = form.save(commit=False)
        try:
            hotel = Hotel.objects.get(
                contact_person=self.request.user.userprofile,  # make sure hotel belongs to user
                id=self.kwargs.get('hotel_id'))
        except Hotel.DoesNotExist:
            raise Http404
        photo.hotel = hotel
        photo.save()
    
  • Отслеживайте загруженные изображения во время сеанса пользователя и связывайте загруженные изображения с отелем после отправки HotelCreationForm:

    # in PhotoUploadView, post()
    if form.is_valid():
        photo = form.save()
        session = self.request.session
        if not session.get('uploaded_photos'):
            session['uploaded_photos'] = [] 
        session['uploaded_photos'].append(photo.id)
        data = {'is_valid': True, 'name': photo.file.name, 'url': photo.file.url}
    
    # in HotelCreationView, form_valid() or post():
    hotel = form.save()
    session = self.request.session
    if 'uploaded_photos' in session:
        Photo.objects.filter(id__in=session['uploaded_photos']).update(hotel=hotel)
        del session['uploaded_photos']
    

    Примечание что в этом случае вам нужно оставить null=True, blank=True в поле hotel в вашей модели Photo, так как вы сначала сохраняете фотографию без отеля.

    Также обратите внимание, что если пользователь никогда не закончит сохранение отеля, фотографии все равно будут храниться в БД и хранилище, без привязки к отелю, поэтому вам, вероятно, придется время от времени убирать (удалить все фотографии, у которых нет отеля).

0 голосов
/ 18 февраля 2020

В моделях нет ничего особенного, но вам нужно внести некоторые изменения в Photo модели

class Photo(models.Model):
    title = models.CharField(max_length=255, blank=True)
    file = models.ImageField(upload_to='hotel_photos')
    hotel = models.ForeignKey(Hotels,on_delete=models.SET_NULL, related_name='photos')

Теперь вы должны сначала создать объект гостиницы, а затем, когда вы нажимаете на панораму для добавления изображений, это должно установите отель, передав ему идентификатор отеля или что-то в этом роде. Когда в других случаях вы будете использовать hotel объект, вы можете напрямую получить доступ к его фотографиям, используя related_name против него.

Существуют и другие способы решения этой проблемы, если вы не можете заранее создать отели или что-то еще так, но для текущего сценария этот подход будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...