Preserve url in django ImageField when copying to a new model instance - python

I am performing a data migration, moving images from inside one model out to their own model.
class OldCrappyModel(models.Model):
...
original_image = models.ImageField(upload_to=upload_original_image, null=True, blank=True)
my_events_image = models.ImageField(upload_to=upload_my_promotions_image, null=True, blank=True)
...
class MyImage(models.Model):
original_image = models.ImageField(upload_to=upload_original_image, null=True, blank=True)
my_events_image = models.ImageField(upload_to=upload_my_promotions_image, null=True, blank=True)
...
The upload_to methods just return a unique name for the file.
When I go to migrate them (in a South datamigration):
i = MyImage(
my_events_image = old.my_events_image,
original_image = old.original_image,
)
i.save()
The problem is, we have some images that are not in the same place as the new ones. When the copy happens, it translates the url from the old ImageField into a url that would work for the new one. For example:
old.url comes out to path/to/something/awesome.jpg
i.url becomes new/media/root/awesome.jpg
How can I preserve the ImageField without anything happening to it when it saves? I'd like to avoid having to make new copies of all the files if possible.

Disable upload_to for the duration of the migration. Set the upload_to manually while copying instances.
After the migration, enable it back.

Related

Problem when deleting ImageField from database

models.py:
Picture = models.ImageField('Picture', null=True, blank=True)
When I give the command
person.Picture.delete()
the picture is deleted from the directory, but in the database still has the record of the file path in Picture as shown in image below. How can I delete it?
Set the field to None as well, so:
person.Picture.delete()
person.Picture = None
person.save()
Note: normally the name of the fields in a Django model are written in snake_case, not PascalCase, so it should be: picture instead of Picture.
You need to try
person = Person.objects.get(User=User_)
person.Picture.delete(save=False)
...
person.save()
Try setting the path in your model something like below
Picture = models.ImageField(upload_to='Picture', null=True, blank=True)

Unable to delete object from Django admin panel with MongoDB

I have a Django project using a MongoDB connected by Djongo. I created a simple model which looks like:
from django.db import models
# Create your models here.
class Property(models.Model):
name = models.CharField(max_length=128, blank=False)
property_type = models.CharField(max_length=24, blank=True)
include_on = models.CharField(max_length=256, blank=True)
format_example = models.TextField(blank=True)
notes = models.TextField(blank=True)
After registering the model by using the line admin.site.register(Property) in the admin.py file I end up seeing my model appear. After adding a test Property I see the line
The property “Property object (61226db9f4f416b206c706e5)” was added successfully.
Which tells me the item was added. It also appears on the admin panel but it looks like:
Property object (None)
If I select the property I get an error that says:
Property with ID “None” doesn’t exist. Perhaps it was deleted?
If I try to delete the property I get a ValueError with error of:
Field 'id' expected a number but got 'None'.
Since I am currently learning Django/MongoDB I actually ran across the ValueError once before. The fix was to delete the entire database and start over. The issue is I don't want to run into this in the future and want to know what I have to do to fix it, or correct what I am doing wrong.
I found my answer. Turns out I need to assign a primary key. I fixed this by changing my model to..
class Property(models.Model):
name = models.CharField(primary_key=True, max_length=128, blank=False)
property_type = models.CharField(max_length=24, blank=True)
include_on = models.CharField(max_length=256, blank=True)
format_example = models.TextField(blank=True)
notes = models.TextField(blank=True)

Duplicating an Imagefield on save() - django

I'm working on a project in django, I need to duplicate a picture stored in one model and save it with a different name into another one, I've tried many of the responses I've found but nothing seems to work.
This last try doesn't give me an error but is not duplicating the image, nor storing a copy with the name. I'm running Pillow and Django 3.X
models.py:
class Visualization(models.Model):
kind = models.CharField(max_length=90)
description = models.CharField(max_length=90)
image = models.ImageField(upload_to='visualization', null=True,
blank=True)
class Order(models.Model):
visualization = models.ForeignKey(Visualization,
on_delete=models.CASCADE)
hashed = models.ImageField(upload_to='hashedimages', null=True,
blank=True)
def save(self):
super().save()
self.hashed = self.visualization.image
self.hashed.name = 'randomothername.jpg''
self.hashed.save()

How to save multiple files under in 1 django model

I'm fairly new to Django. I have a model copy (exam copy of a student), the model copy will contain a student test or exam copy and a mark, usually, i would use a FileField and save the copy to the object, but my problem is that a copy could contain many files (page 1, 2, 3 etc)
I was thinking about using a CharField instead that contains the path to a folder that contains the files for that copy, but I don't have a very good idea on how to do that
and if you have a better way I would for you to share.
here is my model
class VersionCopie(models.Model):
id_version = models.CharField(db_column='id_Version', primary_key=True, max_length=100)
numero_version = models.IntegerField(db_column='numero_Version', blank=True, null=True)
note_copie = models.FloatField(db_column='note_Copie', blank=True, null=True)
emplacement_copie = models.CharField(db_column='emplacement_Copie', max_length=10000, blank=True, null=True)
id_copie = models.ForeignKey('Copie', models.CASCADE, db_column='id_Copie', blank=True, null=True)
i just need to know what kind of path i would save to "emplacement_copie"
Well, I think this is classical one-to-many relation. You have probably already implemented something like that by doing id_copie = models.ForeignKey(...)
You should create separate model, representing just one file and containing reference to your VersionCopie. You can still access all files from VersionCopy model, reference is created implictly (see this link).
Example code:
class VersionCopyFile(models.Model):
file = models.FileField( <your arguments> )
version_copy = models.ForeignKey(VersionCopy, on_delete=models.CASCADE)

Django - get_or_create() with auto_now=True

I’m using Django and I'm having a problem with a Python script that uses Django models
The script that I'm using takes data from an api and loads it into my database.
my model:
class Movie(models.Model):
title = models.CharField(max_length=511)
tmdb_id = models.IntegerField(null=True, blank=True)
release = models.DateField(null=True, blank=True)
poster = models.TextField(max_length=500, null=True)
runtime = models.IntegerField(null=True, blank=True)
description = models.TextField(null=True, blank=True)
edit = models.DateTimeField(auto_now=True, null=True, blank=True)
backdrop = models.TextField(max_length=500, null=True, blank=True)
popularity = models.TextField(null=True, blank=True)
the script:
movies = tmdb.Movies().upcoming()
results = movies['results']
ids = []
for movie in results:
data, created = Movie.objects.get_or_create(title=movie['title'],
tmdb_id=movie['id'],
release=movie['release_date'],
description=movie['overview'],
backdrop=movie['backdrop_path'],
poster=movie['poster_path'],
popularity=movie['popularity'])
The problem I'm having is that whenever I run the script, the entries are duplicated because the edit field is change, but the purpose I put the edit field is to know when exactly a movie got edited, ie: some other field got changed.
How can I avoid the duplicates, but also keep the edit field in case some real change happened?
but the purpose I put the edit field is to know when exactly a movie
got edited, ie: some other field got changed.
That probably means you are using the wrong function. You should be using update_or_create istead.
A convenience method for updating an object with the given kwargs,
creating a new one if necessary. The defaults is a dictionary of
(field, value) pairs used to update the object.
This is different from get_or_create, which creates an object if it does not exists, or simply fetches it when it does exist. update_or_create is the one that does the actually updating.
However, changing to this method doesn't solve this:
How can I avoid the duplicates, but also keep the edit field in case
some real change happened?
Duplicates are created because you do not have a unique index on any of your fields. Both get_or_create and update_or_create require that you have a unique field. It seems that the following change is in order:
class Movie(models.Model):
title = models.CharField(max_length=511)
tmdb_id = models.IntegerField(unique=True)

Categories

Resources