Photologue ImageModel required field question (and how to override) - django

I have a model that inherits from Photologues 'ImageModel'. The user can upload photos and everything works fine, however the problem I am running into is when I am creating a form to edit a photo object. Since the ImageModel.image is a required field, and I can't prepopulate a FileField widget with a file already uploaded, if the user doesn't upload a new image to overwrite the old one they get an error. The error pops up in form.save() which I am using to get the rest of the fields updated right. Is there some way I can hook in and try say "since I know I am just editing an image, I know one has already been uploaded, so don't worry if the form field is empty".
Any thoughts?

You have a couple options. One, you can modify the Photologue source to make that field optional. The other, and if it will work for you the one I'd recommend, is to check out my newer library django-imagekit: http://bitbucket.org/jdriscoll/django-imagekit/wiki/Home
ImageKit is basically JUST the ImageModel part of Photologue but it's much more flexible and easier to work with. ImageKit's ImageModel works on top of the models that you define so fields can be configured how ever you please.

Related

Django viewable or clickable filepath field

I'm a little new to the inter-workings of Django and I would like to display a simple dynamic folder path field that opens to the given path when clicked so a user can view all the files in that path. I'm trying to do this in django admin site change form but am unclear and confused of how to do so. Below is my model.
class Order(models.Model):
order_number = models.IntegerField(verbose_name='LS #', unique=True)
order_name = models.ForeignKey(recs.RecipeControl, related_name='recipe')
# Something like this is I think what I want.
folder_path = models.FilePathField(path=get_path)
def get_path(self):
return str(self.order_number)+"_"+self.order_name
I'm puzzled as how to properly go about this because I can't seem to reference "self" to do this, especially if the record doesn't already exist. I've looked at a few other Q&A's but none of them dealt with the admin site and after a bit of reading I'm convinced that I may have to override one of the save methods but don't understand which one and where to place my method. Thanks in advance
EDIT
After reading through the comments recommended below I think what I want is different than what I had originally thought. The folder path still needs to be dynamic.
However, what I'm looking to do is check on new and existing records whether a folder exists in a given directory (MEDIA_ROOT?) based on model data, then create that directory or update it's name if it changes and save the folders path in the FilePathField. I'm pretty confident that this can be done by overriding that save_model method of the ModelAdmin, no?

Why does BaseModelForm update ALL fields, despite documentation saying it does not? Is this a bug?

I'm working on a django project with a legacy DB, using formset to edit a set of rows. There are fields in that DB that I don't want django to update, although I need them in my model. In other words, I want them to be treated as READ-ONLY fields.
Thus, I was happy to read the documentation on saving model formsets, which states:
"When fields are missing from the form (for example because they have
been excluded), these fields will not be set by the save() method. You
can find more information about this restriction, which also holds for
regular ModelForms, in Selecting the fields to use."
https://docs.djangoproject.com/en/1.8/topics/forms/modelforms/#saving-objects-in-the-formset
Indeed, when forms.model.BaseModelForm.save() is invoked, it calls forms.model.save_instance(), nicely passing in all the form fields. BUT than then calls instance.save() WITHOUT passing along the update_fields!! And so ALL the model fields are included in the update query :-(
As a test, I modified forms.model.save_instance() to pass the fields:
instance.save(update_fields=fields)
and voila - the model only saves fields listed by its form.
I'm hoping someone more involved in the django project can tell me if this a bug, or a documentation issue? Should I submit a bug report? Am I missing something - is there some other way I should be enforcing "read only" on those fields?
Using django1.8 and python3.4
I'm not sure why you think this behaviour contradicts that documentation, or why it would need to pass along the fields to update. The instance already has the unchanged data; Django will update the rest of the fields from the form, and save the whole thing.

re-uploading files when django form fails at some point

Am currently working with django and using the forms to render a form different fields. The problem am facing is that I have file field in the form and sometimes when submitting the form and a different field returns an error, the file field "value" disappear, which means must re-select the file again..
Is there a way to maintain the file even when the form returns an error? Any examples I can look at or anything that can help me?
Thanks
See https://github.com/un1t/django-file-resubmit
In Django project you have forms with FileField, ImageField.
Everything works great, but when ValidationError is raised, you have
to reselect all files and images again. It is kind of annoying.
django-file-resubmit solves this problem. It works with FileField,
ImageField and sorl.thumbnail.ImageField.

How to override/update information from POST when creating model

I have a view that handles a POST request and attempts to create a new object. However, I know that some of the POST'd data is invalid... But I want to fix it and go ahead and create the object.
The only way I can figure out to be able to 'fix' data in a ModelForm is to create a 'is_valid()' form. To do this, I can either create the form with the POST data, or I can create it with an already existing instance. Unfortunately, if I use the POST data, because some of it is invalid, the form won't validate and I am thus unable to get to the data in the form to fix it. If I create it with an already existing instance, this works, but when the form is displayed, any remaining errors are for whatever reason ignored (and thus don't show up on the web page.) I've tried a combination of creating the the Model form from the POST data and giving it an instance, but this doesn't seem to help. Additionally, I've tried modifying (a copy of) the POST data, fixing it, and then creating the ModelForm from the 'fixed' POST data. This sort of works, with the exception that I have some ImageFields in my form, and they seem to just be ignored.
Any help would be greatly appreciated. I have looked at every good page that I can find to no avail.
Perhaps there is a better way to do this? The problem I'm trying to solve is that I want to have a model that contains ImageFields. The first time I put up the form, the user needs to 'upload' images for each of the fields. However, if he doesn't update an image for one of the fields, I want the new form to come up with a Image upload button on the fields where images have not been uploaded, and just a text field with the image name for images that have been uploaded.
Edit 9/15/2010:
Ok, I think I can simplify all of the above question into this:
def testing( request ) :
test_form = UserProfileForm()
valid = test_form.is_valid()
return render( 'testing.tmpl', locals(), request )
When the above code is rendered, the 'valid' shows as False (as one might expect), but the 'test_form' renders without any errors. I've read through (if perhaps not understood?) the documentation on Models and ModelForms, and I see that most of the time a ModelForm (in my case: UserProfileForm) is created with a specified 'instance'. However, 1) I don't have an instance yet, 2) I would still expect the non-instance'd Form to display errors. I'm sure there is something I am missing. Please illuminate. :)
One more thing, which perhaps the answer to the above will answer anyway, but as far as I can tell, the is_valid() call is supposed to call the 'clean()' function I defined for the UserProfileForm. However, (not being a python guru) I placed 'raise ValidationError()' at the top of clean(), and when I run the code, no error is shown. Thoughts?
Update: I figured out the problem and the answer is below. Thanks!
You should have a look at how to clean form fields in django. You could either manipulate the data returned from the form there or make any kind of validation!
If your ImageFields are optional then you can still validate them (that they are otherwise correct).
Then it's a matter of adjusting your template to show either the uploaded file name or an file upload field depending on whether they've already uploaded one or not. Actually, it would probably be better to give them both fields in the first case. That's what the automatic admin does (the upload field is labeled "Change").
Well, after figuring out how to use the python debugger (pdb) and the fact that within emacs it kind of 'just works' (wow!?) I was able to find that my (empty) form was not bound. Googling bound forms pointed me to this page:
http://docs.djangoproject.com/en/dev/ref/forms/api/
RTFM'ing I find that I can pass an empty dictionary to my form and then everything starts to behave as I would expect. So, to summarize, there is a big difference between:
test_form = UserProfileForm()
and
test_form = UserProfileForm( {} )
The second version causes the rendering of the form to show all the errors (and to call 'clean()').
With risk of having this deleted by the moderator ;) Thank you to all those who commented and for your patience with a new django developer.

Django - update a model won't delete the old FileField

I am implementing an application with django, which has a model with a FileField:
class Slideshow(models.Model):
name = models.CharField(max_length=30,unique=True)
thumbnail = models.FileField(max_length=1000,upload_to="images/app/slideshows/thumbnails")
and I have an admin backend where django manages the models. I just added the file admin.py and django manages everything for me
from django.contrib import admin
from apps.gallery.models import Slideshow
admin.site.register(Slideshow)
In the backend, it is possible to add, delete and update the slideshows. However, when I try to update a slideshow and change its attribute thumbnail [FileField], django does not delete the old file. Consequently, after several updates the server is filled with many files which are useless.
My question is: how can I make django delete those files automatically after an update?
I would really appreciate your help
I thought much about this problem, and eventually I find out a solution than works well for me. You can find all models in project and connect pre_save and post_delete signals to them.
At the end I made app, which sloves this problem - django-cleanup
I'm sure Django does this by design. It can't know, for example, whether any other models might be using that file. You would also be really surprised if you expected the file to remain and discovered that django deleted it!
However, there's also the issue that as soon as you change the file field, you lose the old file name.
There's an open ticket about that problem: http://code.djangoproject.com/ticket/11663
There's a patch in http://code.djangoproject.com/ticket/2983 which shows how to override __set__ to store the previous file name. Then your model's __save__ method can get access to the previous file name to delete it.