Django: Creating forms for data linked to a user profile - django

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

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)

How to populate Django foreign key with a temporary default value?

In my Django web application, when the user creates an account, a record for their account is created in the auth_user table. Now there is one required field on the signup form, a dropdown box, that they will use to select what type of user they are. This value is used to populate a foreign key field in a second 'profile' table. The problem is that this profile table has numerous other required foreign key fields that also need to be populated and I need to create an initial record for the user in that profile table before they fill out the rest of their profile (and thus setting these other foreign key fields). This may not happen for some time after the account is created. Is there a way to do this in Django? I know you can set FK fields to blank=True, null=True if the field is optional, but this field really is required. I'd like to trick Django into designating it as required with a temporary value, perhaps by adding a record like "TBD" to the table pointed to by the FK. But putting a "TBD" field in the other table seems "unclean" to me. How do I solve this problem?
Here is the view that creates the new user:
def account_create(request):
if request.method == 'POST':
user_form = CreateAccountForm(request.POST)
if user_form.is_valid():
# Create new user object but don't save it.
new_user = user_form.save(commit=False)
new_user.set_password(user_form.cleaned_data['password'])
new_user.save()
Profile.objects.create(user=user, type=user_form.cleaned_data['user_type'])
return render(request, 'account/account_created.html', {'new_user': new_user})
else:
user_form = CreateAccountForm()
return render(request, 'account/create_account.html', {'form': user_form})

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()

How to set User-based form field choices in a django ModelForm (with django-allauth)

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.

Accesing information from a POST form in django 1.6

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.