Assign image to a form field in django.views - django

I am in the middle of a project and I am stuck. I have a edit profile feature where a user can edit their profile. Everytime a profile is created with an empty profile_picture field a default value is provided. But once an image is assigned to field and then deleted. The field gets blank.
What I want is everytime the field becomes None I want to reassign the default image by mentioning the file path.
Heres My view where I save the model form:-
if form.is_valid():
form.save(commit=False)
print(form.cleaned_data)
if 'avatar' in form.cleaned_data:
if form.cleaned_data.get('avatar') is False:
form.cleaned_data['avatar'] = image
form.save()
I want to mention the image path in place of image. Also suggest me some better ways for doing this. Thanks in advance

Related

Django Form initial value for image field

I have a user model with username, and an imagefield. And a django form (not a ModelForm) with the same fields. When a user wants to edit his profile I want to populate the form with user's current values. I tried using
initial = {"username": user.username, "image": user.image}
form = Form(initial=initial)
Then I render the form using form.as_p in a template.
Username is okay but image doesn't show. Is there any way to do it?
Since you already have access to the user object, just substitute "instance" for "initail". You can also pass the some initial data along with the instance object if you want to override specific instance attribute.
user = User.objects.get(pk=1)
form = UserForm(instance=user)

Getting user's old image if no image is selected

I have a form that takes in user data like bio, profile picture, gender, etc. and upon submission either creates this new row about the user or updates the existing row. This will only work if the user uploads an image. If no image is uploaded for the profile picture, then the form doesn't submit. How can I make it so that if the user didn't upload a profile picture, then it'll keep the user's previous profile picture and still submit?
Here's my code:
class ProfileSettings(UpdateView):
model = Profile
template_name = 'blog/settings.html'
form_class = ProfileForm
success_url = reverse_lazy('blog:settings')
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, request.FILES)
if form.is_valid():
bio = form.cleaned_data['bio']
gender = form.cleaned_data['gender']
avatar = form.cleaned_data['avatar']
Profile.objects.update_or_create(user=self.request.user, defaults={'avatar':avatar, 'bio':bio, 'gender':gender})
return HttpResponseRedirect(self.success_url)
I'll give you the quick and dirty - 3 places to solve this:
Javascript - make the form aware of what fields are required and pre-fill if the username already exists (out of scope from your question but just throwing it out there)
In the API endpoint (this seems to be the approach you are going for)
In your model (implement a custom save function that looks to see if new, and compare initial value to subsequent value)
I'll dump options 1 and 3 because they aren't pertinent to your question as asked. I'm assuming user is unique per profile. And I'm assuming that currently the field avatar is required. If you set that to not required then the form post should allow a null value for avatar - How to make FileField in django optional?. You may be thinking, but I don't want that field to be possibly blank - you could always enforce that the first time the post is made that the field is set via the API endpoint itself. If you made that field optional then the form would post but you may want to be more explicit with .update_or_create by actually checking to see if the object already exists and if so require the field or if not confirm that field is set.

Django 1.7 - update a user record using a form

I have created a form to update the existing user profile. But when i save the form it shows the error user already exists.
I used another approach by getting the user profile and then updating each field, but in that case each field has to be validated?
Any clue how to save the form as an update not as a new entry?
I suggest using UpdateView, one of Django's class-based-views for generic editing:
class django.views.generic.edit.UpdateView
A view that displays a
form for editing an existing object, redisplaying the form with
validation errors (if there are any) and saving changes to the object.
This uses a form automatically generated from the object’s model class
(unless a form class is manually specified).
I managed to get the answer, i imported the form to
import the user that i want to edit
u = User.objects.get(username = user_name)
creating the form with values from existing in database and updating with values from POST
user_form = UserEditForm(request.POST,instance=u)
save the form, since it already has existing record it will update
user_form.save()

Django ClearableFileInput - how to detect whether to delete the file

I'm using Django Crispy Forms for my form with an option to upload an image (ImageField in my Model)
The forms renders as I'd expect, with the checkbox to clear an existing file. However when processing the form submission the 'image-clear' checkbox always gives me a 'None' value.
image_clear = form.cleaned_data.get("image-clear")
print image_clear
In the HTML of the page I notice that the input checkbox doesn't have a value attribute, see:
<input id="image-clear_id" type="checkbox" name="image-clear">
So I wondered if this was the issue, but when I look at the rendering in the Django admin site, the corresponding HTML input field doesn't have a value either - yet it still identifies that the image should be removed.
I should note that if I upload a new image, then this works, it's only the case where I'm removing/clearing the image (and it works in Django admin pages, so assume that means my model definition is ok to allow no image to be attached to the model)
So... in my form processing, how do I detect whether or not the image should be removed or not?
I'm sure I'm missing something simple here - and any help much appreciated.
You shouldn't check the checkbox, but check the value of the file input field. If it is False, then you can delete the file. Otherwise it is the uploaded file. See: https://github.com/django/django/blob/339c01fb7552feb8df125ef7e5420dae04fd913f/django/forms/widgets.py#L434
# False signals to clear any existing value, as opposed to just None
return False
return upload
Let me add here my code that solved the problem - I decided to put this logic to ModelForm.clean():
class Document(models.Model):
upload = models.FileField(upload_to=document_name, blank=True)
class DocumentForm(ModelForm):
def clean(self):
cleaned_data = super(DocumentForm, self).clean()
upload = cleaned_data['upload']
if (upload == False) and self.instance.upload:
if os.path.isfile(self.instance.upload.path):
self.instance.upload.delete(False)

Inserting values into a formset

I have a modelform which has a user_id field that I have excluded from the form. This form is made into a modelformset. The reason I have the user field excluded is because it's not an editable value. I don't want that value to go to the HTML form where it can be tampered with by naughty user.
When I try to save this model formset, I get an error saying user_id can't be null. I need someway to add request.user to each form before I save that formset in the view. How can I do this? I know how to add the value to a single instance of a modelform, but I can't figure out how to do it with a formset.
If you are not passing request.user to form, there is no direct way that you can get it in form's save method.
However there is a way, if you want user to be available directly at form's save method, from outside the context. Check out, http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser .
When you are saving formset remeber to:
if formset.is_valid():
instances = formset.save(commit=False)
for instance in instances:
instance.user_id = request.user.id
instance.save()
You no need anything else. BTW I dont't understand why save user id not user object ?