Django multiple pictures one product - django

I have the following problem: I'm programming a webshop and every product has multiple pictures. So this is a one-to-many relation, where the foreign key is in the picture model. However, if i register the models "product" and "picture" to the admin site the user obviously needs to add a product then navigate to the pictures and add a picture and referencing a product within the picture creation process. Instead of this i want the user to be able to create a product and then add multiple pictures in the dropdown menu inside the same subpage inside admin-pannel. How can i accomplish this behaviour? It should look exact like it would with a many-to-many relation. But i don't want to use ManyToManyField sience i already tried it and then it lead to logical issues.
models.py:
class Picture(models.Model):
picture = models.ImageField(upload_to='shop/static/shop/images/')
product = models.ForeignKey(Product, on_delete=models.CASCADE)
def __str__(self):
return self.picture.url
class Product(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
admin.py
admin.site.register(Picture)
admin.site.register(Product)

models.py
class Picture(models.Model):
picture = models.ImageField(upload_to='shop/static/shop/images/')
def __str__(self):
return self.picture.url
class Product(models.Model):
name = models.CharField(max_length=200)
picture = models.ForeignKey(Picture, on_delete=models.CASCADE)
def __str__(self):
return self.name
admin.py
class PictureInline(modeladmin.StackedInline):
model = Picture
class ProductAdmin(admin.ModelAdmin):
inlines = [PictureInline]
admin.site.register(Product, ProductAdmin)
#NOTE: dont register you Picture model because you have put inline in product so from here you can directly put you pictures in the product.

class Picture(models.Model):
picture = models.ImageField(upload_to='shop/static/shop/images/')
def __str__(self):
return self.picture.url
class Product(models.Model):
name = models.CharField(max_length=200)
product = models.ManyToManyField(Picture, blank=True,related_name="product_img")
def __str__(self):
return self.name
Try using this instead.

Related

Edit multiselect field?

So I have a ManyToMany field in my model and Django admin renders it as a multiselect field. It works fine and I have no issues — except that I can't Edit it after creating a record.
I tried Del key, mouse right-click, nothing worked. Looks like I have to delete the record and create it again?
This is the field I want to edit. I want to remove one or two of the above items. I'm on Windows.
Well it looks like there's a simpler solution:
(Courtesy of Webdev Hints)
Here's my models:
class Technology(models.Model):
title = models.CharField(max_length=10)
def __str__(self):
return self.title
class Meta:
verbose_name_plural = 'Technologies'
class Project(models.Model):
title = models.CharField(max_length=100)
description = HTMLField()
technology = models.ManyToManyField(Technology, related_name='projects')
image = models.ImageField(upload_to='projects/')
def __str__(self):
return self.title
And the solution is to add the following to the admin.py:
#admin.register(Technology)
class TechnologyAdmin(admin.ModelAdmin):
pass
class TechnologyInline(admin.TabularInline):
model = Project.technology.through
#admin.register(Project)
class ProjectAdmin(admin.ModelAdmin):
inlines = (TechnologyInline,)
exclude = ('technology',)
Now the ManyToMany filed is editable.

how to create django form with multiplechoicefield and add those value to database

what I want to achieve is user will submit 3 inputs in the form 1) name 2) dropdown to select technician, 3) multiselect dropdown to select multiple products. Once the user submit the details
it will generate one lead in database with value like name,foreignkey of selected technician and id of selected products in different table. I don't know how to achieve this below I have mentioned my approch to achieve what I want. Please let me know if the models need any changes and how I can write a view for the same.
models.py
class product(models.Model):
name = models.CharField(max_length=20)
class technician(models.Model):
name = models.CharField(max_length=20)
class lead(models.Model):
name = models.CharField(max_length=20)
technician = models.ForeignKey(technician,on_delete=models.SET_NULL,null=True) #only single selection
products = models.ManyToManyField(product) #user can select multiple product in dropdown
form.py
class leadForm(form.ModelForm):
products = forms.MultipleChoiceField(queryset=Product.objects.all())
technician = forms.CharField(max_length=30,choices=[(i.id,i.name) for i in Technician.objects.all().values('id','name')
class Meta:
model = lead
fields = ('name','technician')
You should use a ModelMultipleChoiceField [Django-doc] here. The But in fact you do not need to implement the models yourself. You can simply let the Django logic do the work for you.
In order to give a textual representation at the HTML end, you can override the __str__ functions of the models:
class Product(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
class Technician(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
class Lead(models.Model):
name = models.CharField(max_length=20)
technician = models.ForeignKey(Technician, on_delete=models.SET_NULL, null=True)
products = models.ManyToManyField(Product)
Then we can simply define our form with:
class LeadForm(form.ModelForm):
class Meta:
model = Lead
fields = '__all__'
Note: usually classes are written in PamelCase and thus start with an Uppercase.
You can here use a class-based CreateView [Django-doc] for example:
from django.views.generic.edit import CreateView
from app.models import Lead
from app.forms import LeafForm
class LeadCreateView(CreateView):
model = Lead
form_class = LeadForm
template_name = 'create_lead.html'

Add new rows to related model on creation of parent model in Admin

I have models for adding products. The name of the products are in several languages, so I made a on-to-many raltion with a 'Name'-model.
This is my models
class Product(models.Model):
active = models.BooleanField()
class ProductName(models.Model):
productName = models.CharField(max_length=250)
product = models.ForeignKey('Product', on_delete=models.CASCADE)
language = models.ForeignKey('Language', on_delete=models.CASCADE)
def __str__(self):
return self.productName
class Language(models.Model):
language = models.CharField(max_length=55)
languageAbbreviation = models.CharField(max_length=10)
def __str__(self):
return self.language
Now in the admin page of mysite, I want to add product names on creation of a product.
I tried some misarable attempt with some thing I found about 'admin.TabularInline'. But I think that is wrong because nothing is working with that.
Any suggestion about how to solve this is much appreciated!
A model admin like this:
class ProductAdmin(admin.ModelAdmin):
class ProductNameInline(admin.TabularInline):
model = ProductNameInline
fields = ['productName', 'language']
model = Product
inlines = [ProductNameInline]
should provide you with a page that allows you set the name(s) of a product.
Make sure all the necessary static files for the javascript are available.

How to include rows of data in a single django model entry?

I am working on multiple django sites and have been limited in making my project look nice for clients.
For example in the same app I have two models images and image galleries. It would be so much nicer to just have an admin entry for galleries and in that a table of images.
That's exactly what InlineModelAdmin is for. Taken a models.py like this:
class Gallery(models.Model):
name = models.CharField(max_length=100)
class Image(models.Model):
image = models.ImageField()
gallery = models.ForeignKey(Gallery)
You create an admin.py like this and only register an admin class for the Gallery:
class ImageInline(admin.TabularInline):
model = Image
class GalleryAdmin(admin.ModelAdmin):
inlines = [ImageInline]
admin.site.register(Gallery, GalleryAdmin)
This is my solution thanks to Dirk's help.
from django.db import models
PHOTO_PATH = 'media_gallery'
class Gallerys(models.Model):
title = models.CharField(max_length=30, help_text='Title of the image maximum 30 characters.')
slug = models.SlugField(unique_for_date='date', help_text='This is automatic, used in the URL.')
date = models.DateTimeField()
class Meta:
verbose_name_plural = "Image Galleries"
ordering = ('-date',)
def __unicode__(self):
return self.title
class Images(models.Model):
title = models.CharField(max_length=30, help_text='Title of the image maximum 30 characters.')
content = models.FileField(upload_to=PHOTO_PATH,blank=False, help_text='Ensure the image size is small and it\'s aspect ratio is 16:9.')
gallery = models.ForeignKey(Gallerys)
date = models.DateTimeField()
class Meta:
verbose_name_plural = "Images"
ordering = ('-date',)
def __unicode__(self):
return self.title
import models
from django.contrib import admin
class ImageInline(admin.TabularInline):
model = Images
class GallerysAdmin(admin.ModelAdmin):
list_display = ('title', 'date', 'slug')
inlines = [ImageInline]
admin.site.register(models.Gallerys,GallerysAdmin)

How can I let a user to post several images to one model?

I have one listing model :
class Listing(models.Model):
owner = models.ForeignKey(User, verbose_name=_('offerer'))
title = models.CharField(_('Title'), max_length=255)
slug = models.CharField(editable=False, max_length=255)
price = models.PositiveIntegerField(_("Price"), null=True, blank=True)
description = models.TextField(_('Description'))
time = models.DateTimeField(_('Created time'),
default = datetime.now,
editable = False
)
Then I have one ListingImage, which holds the pictures of the listing:
from photologue.models import ImageModel
class ListingImage(ImageModel):
pictures = models.ForeignKey(Listing, related_name="images")
forms.py
class ListingForm(forms.ModelForm):
class Meta:
model = Listing
exclude = ('owner',)
def __init__(self, *args, **kwargs):
super(ListingForm, self).__init__(*args, **kwargs)
Why in the upload page , there is no field to upload a picture??
ListingImage has a ForeignKey to Listing, so a ModelForm for Listing has nothing to do with ListingImage.
You shouldn't be expecting a ModelForm for the Listing model to show you anything but the Listing model. ListingImage is a reverse relationship to the Listing model.
If this was a ModelAdmin, you'd get the admin site to show you these reverse relationships by defining inlines:
http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin
Since it doesn't look like you're talking about the admin panel, you're looking at InlineModelFormsets: http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#using-an-inline-formset-in-a-view
Also, you could show us your views so that we can see the whole picture.