Liondancer
Liondancer

Reputation: 16469

Performing logic before adding model object and updating database in django

When I add an object through my admin.py, how do I perform extra logic before adding the object?

For example, I click ADD MEDIA button within my admin and add a media object:

enter image description here

Notice how under Location there is a value Video Intro. I want that value to appear only once. If it exists, change the other object have a Location value to None.

I want this logic to perform before adding the new model object. Now sure where to make changes and how to do so.

Here is the project structure:

enter image description here

Here is my admin.py:

class MediaAdmin(admin.ModelAdmin):
    search_fields = ["name", "file"]
    list_display = ("name", "media_type", "location", "url", "album", "display", "thumbnail", "filesize")

    def display(self, media_obj):
        return format_html('<a href="%s">%s</a>' % (media_obj.file.url, media_obj.file.name))

    def filesize(self, media_obj):
        return self.convert_size(media_obj.file.size)

    def convert_size(self, size):
        if (size == 0):
            return '0 B'
        size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
        i = int(math.floor(math.log(size,1024)))
        p = math.pow(1024,i)
        s = round(size/p,2)
        return '%s %s' % (s,size_name[i])

    def thumbnail(self, media_obj):
        # pdb.set_trace()
        # location = os.path.join(settings.MEDIA_URL, media_obj.file.name)
        location = media_obj.file.url
        thumbnail_html = "<a href=\"{0}\"><img border=\"0\" alt=\"\" src=\"{1}\" height=\"80\" /></a>".format(location, location)
        return format_html(thumbnail_html)


class MediaInline(admin.TabularInline):
    model = Media

class AlbumInline(admin.TabularInline):
    model = Album

admin.site.register(Media, MediaAdmin)
admin.site.register(Album)

Here is my models.py

class Media(models.Model):
    LOCATION = (
        ("video_intro", "Video Intro"),
        ("logo", "Logo"),
        (None, "")

    )

    TYPE = (
        ("video", "Video"),
        ("gif", "GIF"),
        ("picture", "Picture"),
        ("audio", "Audio")
    )
    name = models.CharField(max_length=50, blank=True)
    location = models.CharField(choices=LOCATION, default=None, max_length=500, null=True)
    uploaded = models.DateTimeField(auto_now_add=True)
    media_type = models.CharField(max_length=50, choices=TYPE, default=None)
    album = models.ForeignKey('Album', blank=True, null=True)
    file = models.FileField(upload_to="media/")
    url = models.CharField(max_length=2083, blank=True, null=True, default=None)
    description = models.TextField(blank=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = "Media"

Upvotes: 0

Views: 342

Answers (2)

bignose
bignose

Reputation: 32309

If you mean that you want to customise the creation of a new instance of the model (i.e. a new record in the table), customise the save method of the model.

The save method is called to store the (new or modified) instance to the database. You can perform any other processing there to “hook” into that save event.

Upvotes: 2

durdenk
durdenk

Reputation: 1660

Use Unique Together model meta, so you can be sure there will be only one video intro. No matter its been added via frontend or admin interface.

But I dont think this option does enforces dropdown menus.

Upvotes: 1

Related Questions