I am new at Django (and Python) and was wondering about the ImageField property of a class. My example is about users of my website. I need 3 sizes of each picture of a user:
* user1-200-200.png
* user1-120-120.png
* user1-60-60.png
Of course I want only 1 file input type.
Should I create 3 properties and resize the one from the form for all properties:
class UserProfile(models.Model):
user = models.OneToOneField(User)
slug = models.CharField(max_length=30)
avatar_200_200 = models.ImageField(null=True, blank=True, upload_to="images/")
avatar_120_120 = models.ImageField(null=True, blank=True, upload_to="images/")
avatar_60_60 = models.ImageField(null=True, blank=True, upload_to="images/")
Can I use no property and do what I did in PHP, resize the images several times, move them to the proper folder and in the website, use the session to find them (I always rename the images and transform them to png).
I don't know what to do and what's possible to do and what's the best. Thanks for your advices.
Sure you can do that but you will have to reimplement some of built-in django features like file uploading, storage support, width/height calculating/saving etc.
Related
I need a way to have different upload and download URLs for ImageField. I want to upload the image to AWS S3 and while accessing the image I want the image to route through CDN (in my case Fastly).
def get_avatar_upload_path(identity, filename):
file_ext = filename.split('.')[-1]
file_name = f'{uuid.uuid4()}.{file_ext}'
return f'{settings.AWS_MEDIA_PREFIX}{identity.uuid}/{file_name}'
class Identity(identity_revision_base):
"""
Identity model. Ties a user to a chat identity.
"""
badges = models.ManyToManyField(Badge, blank=True)
key = models.UUIDField(_("key"), unique=True, default=uuid.uuid4)
uuid = models.UUIDField(_("UUID"), unique=True, default=uuid.uuid4)
avatar = models.ImageField(upload_to=get_avatar_upload_path, blank=True)
user = models.ForeignKey(
to=settings.AUTH_USER_MODEL,
blank=True,
null=True,
on_delete=models.SET_NULL,
related_name="+",
)
Just like I am specifying upload path in ImageField, I would like a way to do something similar for accessing Image. It also seems that I cannot modify avatar.url once it is created. Is there any way around?
If there is any way, I can override the Model's behaviour to modify the url while accessing.
Did you check django-storages? It takes care of uploading to object store and returns CDN URLs for downloading. Fastly is S3 compatible so it should work.
In general you can also also use model methods with property decorator for getting a custom calculated value from model instances.
NOTE I am not necessarily asking for code to build this, just ideas on how to do this. Links and blog posts for pointers are welcome.
I am building a rest api.
I have a model
class Showcase(models.Model):
title = models.CharField(max_length=50)
description = models.TextField(null=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, related_name="Showcases")
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
slug = models.SlugField(max_length=255, unique=True)
def __str__(self):
return self.title
I am trying to build a functionality where the user that created a showcase can add users that contributed to the project which is the showcase. I was thinking of making this its own model like this:
class Collaborator(models.Model):
post = models.ForeignKey(Showcase, on_delete=models.CASCADE, related_name="collaborated_showcases")
owner = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE, related_name="showcase_owner")
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE, related_name="collaborators")
skill = models.ForeignKey(Skill, on_delete=models.CASCADE, null=True, related_name="creative_type")
role = models.TextField(null=True)
added_on = models.DateTimeField(null=True)
def __str__(self):
return f"{self.user.name} collaborated on {self.post.name}"
The user would have to search for users and then add them as a contributor to the showcase, which is where my brain scrambles a bit.
The other important thing is that I want to be able to randomly go to a user and get ALL the showcases he has contributed to.
As I see it, this structure works fine for your use case, though:
models should always be in singular case (Collaborator)
related_names should be lower case (related_name="showcases")
and I prefer to explicitly spell out all related_names, so I'd add
Collaborator.post related name collaborated_showcases
Collaborator.user related name collaborators
Showcase.user related_name owned_showcases
Then,
To find an user's owned showcases, Showcase.objects.filter(user=user)
To find an user's collaborated showcases, Showcase.objects.filter(collaborators=user) (I think)
I'd suggest having a Collaborator object for the owner user as well, so you can show their role more easily as well as make these queries simpler.
I'm fairly new to Django CMS, and I've inherited a website with these specs:
Django 1.10.8
Django CMS 3.4.5
Python 2.7
Unfortunately, there is no option to upgrade at the moment. Also, please pardon if I the terminology wrong - I'd appreciate corrections.
I have a Staff app with models for Staff and StaffTranslation (etc), and I have a task to update the admin to allow adding one or more links to each StaffTranslation. However, I'm having trouble identifying the best way to do this, and what components to use.
I have identified the djangocms-link plugin, which could be a possibility, but I can't find instructions on how to add multiple instances to a model or admin page. Also, the latest version requires Django 1.11, at minimum.
I have also found the PageSmartLinkField - which seems smart - but I haven't been able to discover how to integrate it with data for the StaffTranslation object or how to display it on the admin page for that object.
I would appreciate any suggestions as to how to structure this - it seems like a simple enough task, I think I am just missing a piece or two, of the puzzle.
The end purpose is to have zero-or-many links on a StaffTranslation (which has its own admin page), with the ability to add at least url and link text to each of them. It would be smart if there is some UI helper, allowing for easy selection of internal links, but a text field would be ok.
EDIT: the StaffTranslation model
class StaffTranslation(TimeStampedModel):
staff = models.ForeignKey(Staff, related_name='translations')
language = models.ForeignKey(Language)
specialist_work_title = HTMLField(max_length=128, null=True, blank=True) # SpecialistWorkTitle
description = HTMLField(null=True, blank=True) # PersonText
experience = HTMLField(null=True, blank=True) # Experience
phone_office = models.CharField(max_length=128, null=True, blank=True) # OfficePhone
phone_cell = models.CharField(max_length=128, null=True, blank=True) # CellPhone
mentions = HTMLField(null=True, blank=True) # Mentions
education = HTMLField(null=True, blank=True) # Education
other_qualifications = HTMLField(null=True, blank=True) # OtherQualifications
meta_title = models.TextField(null=True, blank=True) # MetaTitle
meta_keywords = models.TextField(null=True, blank=True) # MetaKeywords
meta_description = models.TextField(null=True, blank=True) # MetaDescription
legacy_data = models.TextField(null=True, blank=True)
objects = querysets.StaffTranslationQuerySet.as_manager()
# I would like to add something here like links = models.ForeignKey(Link, related_name='links') - so should I make a Link model and add as a many to many relation, and how do I integrate that into the admin?
I left out the functions defined on the model.
Again, it would be nice to upgrade, but that won't happen until the summer at the earliest, and this task has to be resolved now. :)
I think a solution for you here will be a placeholder field so you can add CMS plugins like any other plugin, for each instance of this model. For example;
from cms.models.fields import PlaceholderField
class StaffTranslation(TimeStampedModel):
...
content = PlaceholderField(
'staff_translation'
)
Then in your detail view template you do {% render_placeholder object.content %} and it'll show a placeholder for that object like it would for placeholders in any standard page template.
You can obviously then add any CMS plugins, links or otherwise, and the'll render alongside the other attributes on your StaffTranslation instance.
The docs on this are here; http://docs.django-cms.org/en/latest/how_to/placeholders.html
I have a Django model class which encompass various types of model classes like:
Content > (Audio, Video, Image)
I want to perform queries on this parent model like Content.objects.filter() or Content.objects.recent(). How do i come about this? Presently i am using django's concrete model inheritance, which I suppose impose lot of overheard on the db performance by using joins for the parent classes. I cannot use abstract class because that would not permit me to perform queries on the parent class. Here are my models definitions:
class BaseContent(models.Model):
"""
Concrete base model to encompass all the local and social content.
We need a single queryset for all the content on the app.
"""
title = models.CharField(_('title'), max_length=255, default='')
description = models.TextField(_('description'), default='', blank=True)
publisher = models.ForeignKey(settings.AUTH_USER_MODEL)
allow_comments = models.BooleanField(default=False)
is_public = models.BooleanField(default=True)
created = AutoCreatedField(_('created'))
objects = BaseContentManager()
class Video(BaseContent):
ACTIVITY_ACTION = 'posted a video'
UPLOAD_TO = 'video_files/%Y/%m/%d'
PREVIEW_UPLOAD_TO = 'video_frames/%Y/%m/%d'
video_file = models.FileField(_('video file'), upload_to=UPLOAD_TO)
preview_frame = models.ImageField(
_('Preview image'), upload_to=PREVIEW_UPLOAD_TO, blank=True,
null=True)
category = models.ForeignKey(VideoCategory, blank=True, null=True)
num_plays = models.PositiveIntegerField(blank=True, default=0)
num_downloads = models.PositiveIntegerField(blank=True, default=0)
Thanks in advance.
I've had a similar scenario which i have solved using an external named Django Polymorphic, the library seemed to work seamlessly. A few major projects use Django Polymorphic including Django-shop.
Link:
https://github.com/chrisglass/django_polymorphic
Don't quote me on this but i've read a few sources in the past that have mentioned that django_polymorphic models does not have the same performance issues caused by the standard Django ORM concrete inheritance implementation.
In my project I have an app with a school model and a schoolsuggestion model.
The school model has fields for various images, like logo, seal, etc:
seal_image = models.ImageField(upload_to="sealimgs", null=True, blank=True)
logo_image = models.ImageField(upload_to="logos", null=True, blank=True)
The schoolsuggestion model has a field for what the corresponding school field is, and an image field.
field_name = models.CharField(max_length=255, default="")
image_field = models.ImageField(upload_to='img', null=True, blank=True)
When a school suggestion is approved, I overwrote save so that it will get the associated school's field via getattr(field_name) and set it with setattr(field_name, image_field) (I'm simplifying the syntax, but you get the idea).
Problem is, the file is still being saved in img, presumably because I'm using setattr and not the image field specific save, which would have uploaded it to the correct directory.
So how do I do this? It makes sense that I could maybe get the upload_to value of the attribute somehow, resave the image with that filepath somehow, and then use setattr on the resaved image, but I can't figure out how to do the first two.
I modified the upload to to this function and included it in the file above the class def:
def get_upload_to(instance, filename):
return School._meta.get_field(instance.field_name).upload_to+"/"+filename