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)
Related
models.py
class Product(models.Model):
title = models.CharField(max_length=200)
description = models.TextField()
price = models.DecimalField(decimal_places=5,max_digits= 1500)
summary = models.TextField()
featured = models.BooleanField()
def __str__(self):
return self.title
# return f'product title:{self.title}-product price:{self.price}'workok
class Meta:
ordering = ('-price',)
class Opinion(models.Model):
name = models.CharField(max_length=20)
email = models.EmailField(max_length=20)
body = models.TextField()
opinion_date = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=False)
product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='opinion_set')
def __str__(self):
return f'({self.name}) add opinion about ({self.product})'
forms.py:
from django.forms import ModelForm
from .models import Product #space after from keyword
class OpinionModelForm(ModelForm):
class Meta:
model = Product
fields = ['name','email','body','product']
invalid in code line :
fields = ['name','email','body','product'] #---- NOT WORK !!!
, but if i change above code to :
fields = "__all__" # ----it is WORKing ok without any problem !!
question : what is the error? I am not need all the fields in the Product model (like active boolean field), I need only 'name','email','body','product' fields .
According to the error and the code you provided the main problem is that you made a mistake in chosing model in serializer:
class OpinionModelForm(ModelForm):
class Meta:
model = Product
fields = ['name','email','body','product']
Serializer name is OpinionModelForm and listed fields belong to Opinion so I guess you actually wanted to serialize Opinion and no Product as you defined at this line:
model = Product
Simply change it to:
model = Opinion
How to implement multiple file upload in Django with two models?
I have 1 form but two models that make two forms
models.py
class Ads(models.Model):
title = models.CharField(max_length=85, blank=False)
class Images(models.Model):
ad = models.ForeignKey(Ads, related_name='images', on_delete=models.CASCADE)
image = models.ImageField(blank=True, upload_to='')
thumbnail = models.BooleanField(default=False)
views.py
class CreateAd(CreateView):
model = Ads
form_class = CreateAdForm
success_url = reverse_lazy('index')
forms.py
class CreateAdForm(forms.ModelForm):
class Meta:
model = Ads
fields = ('title',)
class ImageForm(forms.ModelForm):
class Meta:
model = Images
fields = ('image', )
Basically you are looking for django formset
formset is a layer of abstraction to work with multiple forms on the same page.
I really need somebody to explain/show me how I can achieve a TabularInline display in the django admin console of my example. Could somebody help me out?
My models are as follows:
from django.db import models
class Player(models.Model):
player_id = models.IntegerField(primary_key=True)
team = models.ForeignKey(Team)
player_name = models.CharField(max_length=140)
position = models.CharField(max_length=10)
def __str__(self):
return '%s' % (self.player_name)
class MatchdayStats(models.Model):
MATCHDAY_STATS_ID = models.AutoField(primary_key=True)
appeared = models.BooleanField(default=False)
goal = models.IntegerField(default=0)
minutes_under_60 = models.BooleanField(default=False)
minutes_60 = models.BooleanField(default=False)
assist = models.IntegerField(default=0)
def __str__(self):
return '%s' % (self.MATCHDAY_STATS_ID)
class PlayerGameweekStats(models.Model):
PLAYER_GAMEWEEK_ALLSTATS_ID = models.AutoField(primary_key=True)
player = models.ForeignKey(Player)
gameweek = models.ForeignKey('fixturesresults.Gameweek')
matchday_stats = models.ForeignKey(MatchdayStats)
def __str__(self):
return '%s (gw=%s,msid=%s)' % (self.player.player_name,self.gameweek.GAMEWEEK_ID,self.matchday_stats.MATCHDAY_STATS_ID)
I would like there to be a tabular display for the PlayerGameweekStats model, where you can enter MatchdayStats fields for each player.
The admin code below causes a Foreign Key error <class 'playerteamstats.models.MatchdayStats'> has no ForeignKey to <class 'playerteamstats.models.PlayerGameweekStats'>
class StatsInLine(admin.TabularInline):
model = MatchdayStats
class PlayerGameweekStatsAdmin(admin.ModelAdmin):
list_display = ('player', 'gameweek')
exclude = ('gameweek')
inlines = [
StatsInLine,
]
admin.site.register(PlayerGameweekStats, PlayerGameweekStatsAdmin)
To build TabularInline models need to be connected with ForeignKey.
From Django docs example:
models.py:
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
author = models.ForeignKey(Author)
title = models.CharField(max_length=100)
admin.py:
from django.contrib import admin
class BookInline(admin.TabularInline):
model = Book
class AuthorAdmin(admin.ModelAdmin):
inlines = [
BookInline,
]
In you case you need to have ForeignKey to PlayerGameweekStats in MatchdayStats.
Please have a look at my models.
class BackgroundImage(models.Model):
user = models.ForeignKey(User)
image = models.ImageField(upload_to=get_upload_file_name)
caption = models.CharField(max_length=200)
pub_date = models.DateTimeField(default=datetime.now)
class ProfilePicture(models.Model):
user = models.ForeignKey(User)
image = models.ImageField(upload_to=get_upload_file_name)
caption = models.CharField(max_length=200)
pub_date = models.DateTimeField(default=datetime.now)
class Album(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=200)
pub_date = models.DateTimeField(default=datetime.now)
class Meta:
ordering = ['-pub_date']
verbose_name_plural = ('Albums')
def __unicode__(self):
return self.name
class Photo(models.Model):
user = models.ForeignKey(User)
album = models.ForeignKey(Album, default=3)
image = models.ImageField(upload_to=get_upload_file_name)
caption = models.CharField(max_length=200)
pub_date = models.DateTimeField(default=datetime.now)
How do I get all the images of Photo, ProfilePicture and BackgroundImage from their image field in one set. And then filter them by -pub_date to display in the template? Please help me out. Will be much much appreciated! Thank you.
Edit
N.B: I need ProfilePicture and BackgroundImage to work with the UserProfile like this:
from django.db import models
from django.contrib.auth.models import User
from profile_picture.models import ProfilePicture
from background_image.models import BackgroundImage
class UserProfile(models.Model):
user = models.OneToOneField(User)
permanent_address = models.TextField()
temporary_address = models.TextField()
profile_pic = models.ForeignKey(ProfilePicture)
background_pic = models.ForeignKey(BackgroundImage)
def __unicode__(self):
return self.user.username
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
There is an InheritanceManager provided as part of django-model-utils which allows you to do this, see docs.
To install in Linux / Mac:
sudo pip install django-model-utils
Annoyingly, installing using easy_install or pip on windows is not quite as straight forward, see: How do I install Python packages on Windows?. A quick and dirty method is to download the django-model-util/ directory from here into the top directory of your django project, this is handy if you intend to copy the entire project across for deployment to a production webserver.
In order to use the InheritanceManager, the models need to be refactored slightly:
from django.db import models
from django.contrib.auth.models import User
from datetime import datetime
from model_utils.managers import InheritanceManager
get_upload_file_name = 'images/' # I added this to debug models
class BaseImage(models.Model):
user = models.ForeignKey(User)
image = models.ImageField(upload_to=get_upload_file_name)
caption = models.CharField(max_length=200)
pub_date = models.DateTimeField(default=datetime.now)
objects = InheritanceManager()
class BackgroundImage(BaseImage):
pass
class ProfilePicture(BaseImage):
pass
class Album(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=200)
pub_date = models.DateTimeField(default=datetime.now)
class Meta:
ordering = ['-pub_date']
verbose_name_plural = ('Albums')
def __unicode__(self):
return self.name
class Photo(BaseImage):
album = models.ForeignKey(Album, default=3)
All the Image models now inherit from a common super class which creates an instance of the InheritanceManager. I've also moved up all the duplicated attributes into the superclass, but this isn't strictly necessary, using InheritanceManager means that any attributes which are not present in BaseImage can still be accessed in the template.
To retrieve a list ordered by -pubdate:
BaseImage.objects.select_subclasses().order_by("-pub_date")
To use in a view:
def recentImages(request):
r = BaseImage.objects.select_subclasses().order_by("-pub_date")[:20]
return render_to_response("recentImages.html", { "imageList" : r })
To use in a template:
{% for photo in imageList %}
<img src="{{ photo.image.url }}" />
{% endfor %}
Is this something like what you are looking for?
Edit
The following code will still work fine, with the new models:
class UserProfile(models.Model):
user = models.OneToOneField(User)
permanent_address = models.TextField()
temporary_address = models.TextField()
profile_pic = models.ForeignKey(ProfilePicture)
background_pic = models.ForeignKey(BackgroundImage)
Just make sure the names of the last two models in the ForeignKey relationship are correct!
I am quite newbie in Django world. My question is I ve two models shown below. It works quite well with Grapelli and inline-sortables. Only problem is whenever I add a new foreign key for "equipment" or "image type" fields. They don't show up in the drop down menu of newly added inline rows. I went through internet but couldn't find a smilar problem and a solution.
I would appreciate some help with this.
My model is:
from django.db import models
from datetime import datetime
from thumbs import ImageWithThumbsField
from positions.fields import PositionField
class Artist(models.Model):
name = models.CharField(max_length=55)
def __unicode__(self):
return self.name
class ImageType(models.Model):
name = models.CharField(max_length=55)
def __unicode__(self):
return self.name
class Equipment(models.Model):
name = models.CharField(max_length=55)
def __unicode__(self):
return self.name
class Image(models.Model):
name = models.CharField(max_length=255)
image_file = models.ImageField(upload_to = "images/%Y-%m-%d")
Image_Type = models.ForeignKey(ImageType)
upload_date = models.DateTimeField('date_published',default=datetime.now)
artist = models.ForeignKey(Artist)
equipment = models.ForeignKey(Equipment)
order = PositionField(collection='artist')
def __unicode__(self):
return self.name
class Meta:
ordering = ['order']
And My admin.py is:
from gallery.models import Image,ImageType,Artist,Equipment
from django.contrib import admin
class ImageUploadAdmin(admin.ModelAdmin):
fields = ['name','artist','equipment','image_file','Image_Type','upload_date']
list_filter = ['upload_date']
date_hierarchy = 'upload_date'
class ImageInline(admin.TabularInline):
model = Image
list_display = ('name','equipment','image_file','Image_Type','upload_date')
sortable_field_name = "order"
exclude = ('upload_date',)
extra = 0
class ArtistAdmin(admin.ModelAdmin):
inlines = [
ImageInline,
]
admin.site.register(Artist,ArtistAdmin)
admin.site.register(Image, ImageUploadAdmin)
admin.site.register(ImageType)
admin.site.register(Equipment)