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)
Related
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.
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()
I'm using Django 1.8 and django-allauth. I have a simple form with a dropdown menu that allows my Users to choose a Character model.
I have a UserCharacter model that looks like this:
class UserCharacter(models.Model):
user = models.ForeignKey(User)
character = models.ForeignKey(Character)
is_default = models.BooleanField(default=False)
In my main Form I'm only displaying the "character" field, which appears as a dropdown menu of Character objects. So far, so good - users can select a Character and it is saved as a UserCharacter association.
What I'm trying to do is display all Character objects that don't already have a UserCharacter linked to the currently logged in User. I would normally use the limit_choices_to feature, like so:
character = models.ForeignKey(Character, limit_choices_to={'id__in': UserCharacter.objects.filter(user_id=[USER_ID]))
my problem is, I don't know how to get access to the current user object from the UserCharacter Model or from a ModelForm. I normally need access to the current request to get at the django-allauth logged in user object. normally in place of [USER_ID] is I would put
self.request.user.id
to get the current user's id from django-allauth, but I can't do that from the Model here. How would I go about changing the form choices in the ModelForm based on the current user object?
Thanks so much!
Since this needs the currently logged in user then you have to do it in the View where you override the form characters QuerySet based on your user.
form.character.queryset = Character.objects.filter(....)
You can also pass the request.user to the form and do the filter there in the constructor.
I have a couple of forms, one is created from as a ModelForm and the other is a simple Form. Both of them are used in a request.POST, and to obtain the information from them I am using to different methods:
For the ModelForm form, I do this:
form = ApplicantForm(request.POST)
if form.is_valid():
applicant = form.save(commit=False)
applicant.confirmation_code = '999999'
applicant.save()
For the simple form, I am using:
form = ConfirmationCode(request.POST)
code = request.POST['confirmation_code']
confirmation_id=request.POST['confirmation_id']
As you can see, to access the information in the first form I am using the "form.save.ANYFIELD", and for the second one I am using "request.POST['ANYFIELD']. Is it possible to access the the information in the first form using the request.POST methods even if it hasnt been saved? Which is better?
You can try like this for modelform:
form = ApplicantForm(request.POST)
if form.is_valid():
app_code= form.cleaned_data['confirmation_code'] #assuming confirmation_code is a field in your modelform
.....
You seem a bit confused about what saving is doing in a modelform. When you call form.save(), you're creating a new instance of the model the form is associated with, and (unless you specify commit=False) saving that data to the database. Because you have an instance, you can use any of the normal model instance methods and access patterns.
If you want to use a form without an associated model, you can't call save - because there's nothing to save, and no model to create an instance of - but you should access the data via the form.cleaned_data dictionary after you call form.is_valid(). This is because the data in cleaned_data has been validated according to the rules in the form, and converted into the relevant types where necessary: for instance, if you had an IntegerField in your form called my_number, request.POST['my_number'] will be a string like "3" but form.cleaned_data['my_number'] will be an actual integer, 3.
I'm trying to save data linked to a user profile using a model with User as a foreign key. I can't figure out a way to create a form that allows adding new instances of the data without having the user name in the form itself. I want to have a form that excludes the user foreign key. Everything works fine until I try to add the user id to the form/data that is about to be saved.
How can I take the logged in user, passed back and forth in the request object, and inject it into the data before I save it?
Use a form constructor to give initial values to the form, so like
render_to_response(
'template.html',
{"form" : MyForm(initial={"username": request.user})},
context_instance = RequestContext(request)
)
you can read more at django docs