I am building a django application where users can upload multiple images and store it as an album.
In my current implementation, I have two models Photo and Album. In the Album model I have a many-to-many field to the Photo model. Thus, a user can select multiple photos in the Album model.
Is there a way by which I can implement a photo picker in Album model instead of a simple many-to-many field?
Here is my code:
class Photo(models.Model) :
def get_gallery_path(self, filename):
ext = filename.split('.')[-1]
filename = "%s.%s" % (uuid.uuid4(), ext)
return 'static/uploads/images/gallery/' + filename
uploader = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateField(default=date.today)
image = ProcessedImageField(default='', verbose_name='Image', upload_to=get_gallery_path,validators=[validate_file_size], **processed_image_field_specs)
caption = models.CharField(max_length=200, null=True, blank=True)
def __str__(self):
return str(self.id) + str(self.uploader.username) + str(self.date)
class Meta:
verbose_name_plural = "Photos"
verbose_name = "Photo"
class Album(models.Model) :
title = models.CharField(max_length=200)
uploader = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateField(default=date.today)
description = models.TextField(null=True, blank=True)
tags = models.ManyToManyField(Tag, blank=True)
category = models.ManyToManyField(Category, blank=True)
photos = models.ManyToManyField(Photo, blank=True)
def __str__(self):
return self.title
class Meta:
verbose_name_plural = "Albums"
verbose_name = "Album"
PS: I am only using the built-in admin interface to store data.
Related
I have below models and form.
Brand > Section > Category > Article.
I can pull the existing data out of the database however I have hit a wall. I am trying to create a new article or update an existing article but I'm not sure how I can update the brand, then the Section. The Category I can update and it is connected directly to the Article model. I have been thinking about this for a few days now and tried different models but ultimately i can't think of the best way to connect the models and have them update in the model.
class Brand(models.Model):
def brand_image(instance, filename):
return 'uploads/brand/{0}/{1}'.format(instance.title, filename)
title = models.CharField(max_length=50, unique=True, blank=True, null=True)
image = models.ImageField(upload_to=brand_image, null=True, blank=True)
slug = AutoSlugField(populate_from='title', unique_with='title', blank=True, null=True)
my_order = models.PositiveIntegerField(default=0, blank=False, null=False)
class Meta:
ordering = ['my_order']
def __str__(self):
return self.title or ''
def get_absolute_url(self):
return reverse('brand-list', kwargs={'brand_slug': self.slug})
class Section(models.Model):
title = models.CharField(max_length=50,unique=True, blank=True,null=True)
slug = AutoSlugField(populate_from='title', unique_with='title',blank=True,null=True)
brand = models.ForeignKey(Brand, on_delete=models.CASCADE, related_name='section', blank=False, null=False)
my_order = models.PositiveIntegerField(default=0, blank=False, null=False)
class Meta:
ordering = ['my_order']
def __str__(self):
return self.title or ''
def get_absolute_url(self):
return reverse('section-list', kwargs={'section_slug': self.slug})
class Category(models.Model):
title = models.CharField(max_length=50, blank=True,null=True)
slug = AutoSlugField(populate_from='title', unique_with='title',blank=True,null=True)
my_order = models.PositiveIntegerField(default=0, blank=False, null=False)
section = models.ForeignKey(Section, on_delete=models.CASCADE,related_name='category', blank=False ,null=False)
class Meta:
ordering = ['my_order']
def __str__(self):
return self.title or ''
def get_absolute_url(self):
return reverse('category-list', kwargs={'category_slug': self.slug})
class Article(models.Model):
title = models.CharField(max_length=100, unique=True, db_index=True)
description = models.CharField(max_length=100, blank=True, null=False)
category = models.ForeignKey(Category, on_delete=PROTECT, related_name='article', null=False, default=1)
slug = AutoSlugField(populate_from='title', unique_with='created__month')
content = HTMLField(null=True,blank=True)
internal = models.BooleanField(default=False)
status = models.CharField(max_length=30, choices=STATUS_CHOICES, default='Draft')
author = models.ForeignKey(User, related_name='author' ,on_delete=PROTECT,null=True)
updated_by = models.ForeignKey(User, related_name='updated_by',on_delete=PROTECT,null=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
video = models.FileField(blank=True, null=True, upload_to='articles/videos')
favourites = models.ManyToManyField(User, related_name='art_favourite', default=None, blank=True)
tags = TaggableManager(related_name='tags', help_text='Comma or space separated list', blank=True)
pinned = models.BooleanField(default=False)
def __str__(self) -> str:
return self.title
def get_absolute_url(self):
return reverse('articles-detail', kwargs={'article_slug': self.slug})
class ArticleForm(forms.ModelForm):
title = forms.CharField(label='Article Title', max_length=100,)
description = forms.CharField(label='Description', max_length=100,required=False)
content = forms.CharField(label='Article Content',widget=CKEditorUploadingWidget(attrs={'cols': 80, 'rows': 30}))
video = forms.FileField(help_text="Valid file Extension - .mp4", required=False, validators=[validate_file_extension])
category = GroupedModelChoiceField(queryset=Category.objects.exclude(section=None).order_by('section'),choices_groupby='section')
internal = forms.BooleanField(required=False, help_text='Is this for internal use only?', label='Internal Article')
class Meta:
model = Article
exclude = ['slug','author','created','updated','updated_by','favourites','votes','views','section']
widgets = {"tags": TagWidget(attrs={"data-role": "tagsinput"})}
Any help or guidance would be greatly appreciated.
Your Article model has a foreign key link to Section for some reason. However your stated heirarchy and models use the following one-to-many relations, which creates a direct link up the chain.
Brand < Section < Category < Article.
This means that by choosing the Category you could also choose Brand and Section. If your Article had a foreign key link to Category instead, then all the information above about groups above Article could be obtained via the article, eg, article.category__section__brand. Changing the category would, by default, update section and brand. You could do this in a single dropdown that contained Category.objects.all - perhaps with the dropdown option text also containing brand and section info for clarity and sorting purposes.
I have start fresh with Django.
I am creating a blog and I need a hint now.
I want to add tags to my posts.
So I created a model for my tags:
class Tag(models.Model):
name = models.CharField(max_length=200, unique=True)
def __str__(self):
return self.name
This is my Post Model
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
updated_on = models.DateTimeField(auto_now= True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
What is the best way, that the user can select in the admin area tags for the post and more than one or create a new tag?
In the Post class, add a field ManyToMany
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
updated_on = models.DateTimeField(auto_now= True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
tag = models.ManyToManyField(Tag)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
You are looking for InlineModelAdmin particulary section regarding
Working with many-to-many models
something as following:
class TagInline(admin.TabularInline):
model = Post.tags.through
class PostAdmin(admin.ModelAdmin):
inlines = [
TagInline,
]
Also you are missing relationship on your model which should be ManyToMany
class Post(models.Model):
...
tags = models.ManyToManyField(Tag)
I have few models. Let's say in home.html I'm using Page model to create simple page structure via admin panel. Now I want add and display inside page multiple galleries. How I should do that ? Is it possible to have inside Page model (in my admin panel) fields with Gallery model ?
class Page(models.Model):
title = models.CharField(max_length=254)
slug = models.SlugField(unique=True)
is_active = models.BooleanField(efault=True)
display_order = models.IntegerField(default=1)
meta_title = models.CharField(max_length=100, null=True, blank=True)
meta_description = models.TextField(null=True, blank=True)
content = RichTextUploadingField(null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
objects = models.Manager()
class Meta:
verbose_name = 'Home page'
verbose_name_plural = verbose_name
def __str__(self):
return self.title
class Gallery(models.Model):
title = models.CharField(max_length=100)
img = OptimizedImageField(upload_to='gallery')
display = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
objects = models.Manager()
class Meta:
verbose_name = 'Gallery'
verbose_name_plural = verbose_name
def __str__(self):
return f'{self.id} {self.title}'
admin panel visualization
I am working on a content management system where a user can create a course for a student to go through.
So far my database has Course, Lesson, and Slide models and I want to connect my Slide model to Quiz, HTML, or Video:
class Course(models.Model):
company = models.ForeignKey(Company, on_delete=models.CASCADE)
slug = models.SlugField(max_length=40, unique=True)
name = models.CharField(max_length=100)
desc = models.CharField(max_length=1000)
date_created = models.DateTimeField(default=datetime.now, blank=True)
last_updated = models.DateTimeField(default=datetime.now, blank=True)
price = models.DecimalField(max_digits=8, decimal_places=2)
is_visible = models.BooleanField(default=True)
def __str__ (self):
return self.name
class Lesson(models.Model):
course = models.ForeignKey(Course, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
order = models.IntegerField()
def __str__ (self):
return self.name
class Quiz(models.Model):
points = models.IntegerField()
# Link to quiz model
class HTML(models.Model):
content = models.TextField(blank=True)
class Video(models.Model):
media_path = models.CharField(max_length=150)
class Slide(models.Model):
lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
slide_type = models.CharField(max_length=100, choices=[("video", "Video"),("image", "Image"), ("text", "Text"), ("quiz", "Quiz")])
notes = models.TextField(blank=True)
last_updated = models.DateTimeField(default=datetime.now, blank=True)
content = models.TextField(blank=True)
reference = models.CharField(max_length=150, blank=True)
def __str__ (self):
return self.title
class QuizQuestions(models.Model):
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
question = models.TextField()
points = models.IntegerField()
Now my slide model could be 1 of 3 things:
Text (raw HTML)
Video
Test
How do I design my database slide model so it can either be a link to a Video, HTML, or Quiz?
My thoughts are:
I could create a module path in Slide and the path would be the
connecting text would be the connection database and a foreign key
to it
Somehow create a foreign key that connects to any of the other
database tables
Let me know if you have any better ideas, I would like a solution that is scalable and I am open to new ideas
There are several ways to implement this.
You can do this with a GenericForeignKey
You can also do this with model inheritance by, for example, having a SlideContent model that each of the Text, HTML, and Video models derive from using multi-table inheritance. Then the Slide can have a foreign key to the SlideContent model.
How can i make field related to field of related model. I have two models: album and photo, album model have boolean field private. How to create field private in photo, which will have False value if album field equal to None and value of album private field if it's not.
models.py:
from django.db import models
from django.contrib.auth.models import User
import os
import uuid
def get_image_path(instance, filename):
return '{}.{}'.format(uuid.uuid4(), filename.split('.')[-1])
class Album(models.Model):
user = models.ForeignKey(User, related_name='albums', on_delete=models.CASCADE)
title = models.CharField(max_length=80, default='New album')
creation_date = models.DateField(auto_now_add=True)
private = models.BooleanField(default=False)
def __str__(self):
return self.title
class Meta:
ordering = ['-creation_date', ]
class Photo(models.Model):
user = models.ForeignKey(User, related_name='photos', on_delete=models.CASCADE)
album = models.ForeignKey(Album, related_name='photos', on_delete=models.CASCADE, null=True, blank=True)
title = models.CharField(max_length=80, default='New photo')
image = models.ImageField(title, upload_to=get_image_path)
creation_date = models.DateField(auto_now_add=True)
# ???
private = models.BooleanField()
# ???
def __str__(self):
return self.title
class Meta:
ordering = ['-creation_date', ]
As #RodXavier said just use property
class Photo(models.Model):
user = models.ForeignKey(User, related_name='photos', on_delete=models.CASCADE)
album = models.ForeignKey(Album, related_name='photos', on_delete=models.CASCADE, null=True, blank=True)
title = models.CharField(max_length=80, default='New photo')
image = models.ImageField(title, upload_to=get_image_path)
creation_date = models.DateField(auto_now_add=True)
#property
def private(self):
return getattr(self, 'album', False)