Upload multiple images for a single product in django - python

I have created some nice models in models.py for uploading multiple images in single products, for different products. The good thing it uses one image model for all products. Now i'm failing to create a perfect forms.py. May someone help me please.
from django.db import models
from django.utils.safestring import mark_safe
from ckeditor_uploader.fields import RichTextUploadingField
from mptt.fields import TreeForeignKey
from mptt.models import MPTTModel
from django.urls import reverse
from django import forms
from django.forms import ModelForm, Form, TextInput, Textarea
def get_upload_path(instance, filename):
model = instance.album.model.__class__._meta
name = model.verbose_name_plural.replace(' ', '_')
return f'{name}/images/{filename}'
class ImageAlbum(models.Model):
def default(self):
return self.images.filter(default=True).first()
def thumbnails(self):
return self.images.filter(width__lt=100, length_lt=100)
class Image(models.Model):
name = models.CharField(max_length=255)
image = models.ImageField(upload_to=get_upload_path)
default = models.BooleanField(default=False)
width = models.FloatField(default=100)
length = models.FloatField(default=100)
album = models.ForeignKey(ImageAlbum, related_name='images', on_delete=models.CASCADE)
class Product(models.Model):
title = models.CharField(max_length=20)
album = models.OneToOneField(ImageAlbum, related_name='model', on_delete=models.CASCADE)
class Vehicle(Product):
STATUS = (
('True', 'True'),
('False', 'False'),
)
brand = models.CharField(max_length=30)
price = models.DecimalField(max_digits=8, decimal_places=2)
mileage = models.IntegerField()
...

Related

How i can realize multiple pagination(drf)

If I'll send get request like thisenter image description here, i need to have multiple pagination (LimitOffset and PageNumber).
models.py:
from django.db import models
class Products(models.Model):
title = models.CharField(max_length=255)
description = models.TextField(blank=True)
photo = models.ImageField(upload_to="photos/%Y/%m/%d/", null=True)
hashtag = models.CharField(max_length=255)
is_hit = models.BooleanField(default=False)
category = models.ForeignKey('Category', on_delete=models.PROTECT, null=True)
def __str__(self):
return self.title
class Category(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
views.py:
from rest_framework import generics
from rest_framework.pagination import PageNumberPagination
from .models import *
from .serializers import ProductsSerializer
class PaginationProducts(PageNumberPagination):
page_size = 2
page_size_query_param = 'page_size'
max_page_size = 2
class ProductsAPIList(generics.ListCreateAPIView):
queryset = Products.objects.all()
serializer_class = ProductsSerializer
pagination_class = PaginationProducts
serializers.py
from rest_framework import serializers
from .models import *
class ProductsSerializer(serializers.ModelSerializer):
class Meta:
model = Products
fields = "__all__"
def get_photo_url(self, obj):
request = self.context.get('request')
photo_url = obj.fingerprint.url
return request.build_absolute_uri(photo_url)
I need something that can help API client choose number of page and quantity of posts on that page. Think that in this case i need NumberPagePagination and LimitOffsetPagination.
I think you don't need to create the custom pagination class.
from rest_framework.pagination import LimitOffsetPagination
class ProductsAPIList(generics.ListCreateAPIView):
queryset = Products.objects.all()
serializer_class = ProductsSerializer
pagination_class = LimitOffsetPagination
The offset value corresponds to the page * size in the original pagination and the limit value corresponds to the size.

Django + Postgres + UUID

UPDATE:
I have got it to work!
What I did was:
Deleted the app
Went into Postgres Admin and deleted the Schema for that app
Created the app again (using a diff name)
Created the Models, URLs, Admin Registering, Views
So I've been trying to add a UUID field to my model, to use it in my URL but I keep getting this error
django.db.utils.ProgrammingError: column "id" is of type bigint but expression is of type uuid
LINE 1: ..._book" ("id", "title", "author", "price") VALUES ('f6b15400-...
^
HINT: You will need to rewrite or cast the expression.
Here is my models.py:
from django.db import models
import uuid
from django.urls import reverse
# Create your models here.
class Book(models.Model):
id = models.UUIDField(primary_key=True, unique=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=200)
author = models.CharField(max_length=200)
price = models.DecimalField(max_digits=6, decimal_places=2)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('book_detail', args=[str(self.id)])
Here is the views.py:
from django.shortcuts import render
from django.views.generic import ListView, DetailView
from .models import Book
# Create your views here.
class BookListView(ListView):
model = Book
template_name = 'books/book_list.html'
context_object_name = 'book_list'
class BookDetailView(DetailView):
model = Book
template_name = 'books/book_detail.html'
context_object_name = 'book'
Here is the urls.py:
from django.urls import path
from .views import BookListView, BookDetailView
urlpatterns = [
path('', BookListView.as_view(), name='book_list'),
path('<uuid:pk>/', BookDetailView.as_view(), name='book_detail'),
]
First add the uuid field as a normal field with a different name:
from django.db import models
import uuid
from django.urls import reverse
class Book(models.Model):
uuid = models.UUIDField(default=uuid.uuid4, unique=True)
title = models.CharField(max_length=200)
author = models.CharField(max_length=200)
price = models.DecimalField(max_digits=6, decimal_places=2)
Run makemigrations and migrate
Now make it primary key:
class Book(models.Model):
uuid = models.UUIDField(default=uuid.uuid4, primary_key=True)
title = models.CharField(max_length=200)
author = models.CharField(max_length=200)
price = models.DecimalField(max_digits=6, decimal_places=2)
This should generate a migration that removes the id field and makes uuid primary key (makemigrations and migrate again).
And finally:
class Book(models.Model):
id = models.UUIDField(primary_key=True, unique=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=200)
author = models.CharField(max_length=200)
price = models.DecimalField(max_digits=6, decimal_places=2)
You may have to adjust the generated migration.

Django Forms created from Model with overfull Queryset Output

I am trying to create a ModelForm for my Model Class "Asset" in Django 3
from django.db import models
from django.contrib.auth.models import User
from django.forms import ModelForm
class Manufacturer(models.Model):
name = models.CharField(max_length=100)
class Asset(models.Model):
serial = models.CharField(max_length=200)
manufacturer = models.ManyToManyField(Manufacturer)
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=200)
I managed to create a Form via the following code
from django import forms
from .models import Manufacturer
class AssetForm(forms.Form):
serial = forms.CharField(max_length=150)
manufacturer = forms.ModelChoiceField(queryset=Manufacturer.objects.all().values('name'))
name = forms.CharField(max_length=200)
description = forms.TextInput()
status = forms.CharField(max_length=200)
category = forms.CharField(max_length=200)
The querySet results in a dropdown being filled out with either "{'name':'Apple'}" or "('Apple',)" depending on using values or values_list respectively. How can I just display the name itself?
Adding the following method to the model fixes the problem:
def __str__(self):
return self.name
This will return the name and only the name to the queryset.

django foreignkey not working

I am still not satisfied with django foreignkey relationship.
below are two classess .
from django.db import models
from django.utils.text import slugify
from django_countries.fields import CountryField
from django.conf import settings
# Create your models here.
class PhotoGallery(models.Model):
title = models.CharField(max_length=255,unique=True)
picture_choices =
models.CharField(max_length=255,choices=PICTURE_CHOICES,default=NTR)
description = models.TextField(default='')
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,related_name='image_uploader')
date_posted = models.DateTimeField(auto_now=True)
views = models.PositiveIntegerField()
likes = models.PositiveIntegerField()
country = CountryField(blank_label='(select country)')
slug = models.SlugField(allow_unicode=True,unique=True)
def __str__(self):
return self.title
from django.contrib import admin
from gallery.models import PhotoGallery
class PhotoGalleryAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('title',)}
And below is class Imagesmodel that has a foreignkey .Calling the PhotoGallery class from class Imagesmodel is not a problem .MY big problem is doing the reverse
class ImagesModel(models.Model):
gala_obj =
models.ForeignKey(PhotoGallery,
related_name='picture_gallery',on_delete=models.CASCADE)
post_image = models.ImageField(upload_to='gallery_pics',
verbose_name='Image')
def __str__(self):
return self.gala_obj.title
and below is my views.py file
`def detailViewPage(request,slug):
#here i wanted to get one image with the given slug
from `ImagesModel`
a = get_object_or_404(PhotoGallery, slug=slug)
selected_pic = a.picture_gallery.all()
#here i wanted to get all images excluding one
with the given slug
object_2 = ImagesModel.objects.exclude(id=selected_pic.id)
.order_by('-id')[:15]
return render(request,'gallery/photogallery_detail.html',{
'selected_pic':selected_pic,
'object_2':object_2,
})`
below is the error i get
The question is not very clear, but I assume you want to get all pictures associated with an object A. In your B model, give your foreignkey a related name:
class B(models.Model):
a = models.ForeignKey(A,related_name='post_title', related_name='pictures')
image = models.ImageField(upload_to='gallery_pics',
verbose_name='Image')
In your views.py:
a = get_object_or_404(A, slug=slug)
b = a.pictures.all()
I don't know why you named your foreignkey 'title', but the above code will get all the pictures associated with the object A.
The following will work also:
a = get_object_or_404(A, slug=slug)
pictures = a.b_set.all()
If you want to get the slug from an object B, then you can do the following:
b = get_object_or_404(B, id=1)
slug = b.a.slug

Django: ManyToMany association name not defined

this is my models.py
from django.db import models
from django.urls import reverse
from django.contrib.auth.models import User
from userprofiles.models import UserProfile
# Create your models here.
import os
class Category (models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Image(models.Model):
owner = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
in_gallery = models.ManyToManyField(Gallery)
title = models.CharField(max_length=100)
def __str__(self):
return self.title
class Gallery(models.Model):
name = models.CharField(max_length=100)
have_images = models.ManyToManyField(Image)
def __str__(self):
return self.name
class ImageInGallery (models.Model):
image = models.ForeignKey(Image)
gallery = models.ForeignKey(Gallery)
line 22, in Image in_gallery = models.ManyToManyField(Gallery)
NameError: name 'Gallery' is not defined
I want to have manytomany relation for Image and Gallery and class ImageInGallery to store the Image~Gallery relation sets.
also, I want images belonging to a certain gallery accessible from a gallery and vice versa, so I put both models.ManyToManyField(Gallery) and models.ManyToManyField(Image) in both classes
whats the reason of the error:
line 22, in Image in_gallery = models.ManyToManyField(Gallery)
NameError: name 'Gallery' is not defined
Place the Gallery model above Image
Ex:
from django.db import models
from django.urls import reverse
from django.contrib.auth.models import User
from userprofiles.models import UserProfile
# Create your models here.
import os
class Category (models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Gallery(models.Model):
name = models.CharField(max_length=100)
have_images = models.ManyToManyField(Image)
def __str__(self):
return self.name
class Image(models.Model):
owner = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
in_gallery = models.ManyToManyField(Gallery)
title = models.CharField(max_length=100)
def __str__(self):
return self.title
class ImageInGallery (models.Model):
image = models.ForeignKey(Image)
gallery = models.ForeignKey(Gallery)
You have duplicated relationship between Image and Gallery.
class Image(models.Model):
in_gallery = models.ManyToManyField(Gallery)
class Gallery(models.Model):
have_images = models.ManyToManyField(Image)
You only need to define one of those fields and then you can use it like the docs describe it.
If you remove the field Gallery.have_images then you can have:
# list all galleries a image is part of
image_instance.in_gallery.all()
# list all images from a gallery
gallery_instance.image_set.all()
Just keep your structure the way you want, and put the model name inside quote
Like:
have_images = models.ManyToManyField("Image")
if the models is in another app, use the name of the app
Ex.
have_images = models.ManyToManyField("app_name.Image")

Categories