Updating user information for an extend user field - Django - django

I'm trying to create an update_profile form. This form will be able to
update extended user information that is not in the original form.
So, I have a form that allows you to create an account. There a lot of
other fields that aren't listed in this form. The rest of these fields
will be found when the user actually logs in and attempts to edit their profile. What I can't figure out
is how to make the save function in that class that allows them to update this information.
Like in the extended user class that I made, I have a save function
that creates a user and saves it. But I don't want to create another
user with this form. I simply want to update the current authenticated
user. I thought there would be an update_user-type function in the
UserManager(), but there isn't. I tried googling and didn't come up
with much. Help Please?

Use ModelForm to create a form to your custom UserProfile model with a subset of the fields:
Using a subset of fields on the form
In some cases, you may not want all
the model fields to appear on the
generated form. There are three ways
of telling ModelForm to use only a
subset of the model fields:
Set editable=False on the model field.
As a result, any form created from the
model via ModelForm will not include
that field.
Use the fields attribute
of the ModelForm's inner Meta class.
This attribute, if given, should be a
list of field names to include in the
form. The order in which the fields
names are specified in that list is
respected when the form renders them.
Use the exclude attribute of the
ModelForm's inner Meta class. This
attribute, if given, should be a list
of field names to exclude from the
form.
https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#using-a-subset-of-fields-on-the-form

Related

Dynamic read-only field in Django Admin

In Django Admin for a Model I want all fields to be:
editable on creation
some of them on updating ( based on the instance fields values on creation).
For example:
2-1. If attribute a has a value, the fields corresponding to attributes c and b to be readonly
2-2. If attributes are empty after creation, should not be editable on updating
I know that for normal forms there is the Field disabled attribute.
I know I need to overwrite Admin form, but I don't have an idea, to know is created or update when form is initialized.
Usually I get the value using clean(), but here I need to get them on initialization in case of updates.
So it is like this:
You can create custom FORMS see here https://docs.djangoproject.com/en/1.8/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form
After that you can add your logic of which form to use by overriding the get_form method. see here https://docs.djangoproject.com/en/1.8/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_form
However you need to make sure your DB will accept the partially submitted data. You can DROP NULL on the specific columns.

Django database inputs not being validated

I have this class:
class Object(models.Model):
value=models.IntegerFiled(validators=[MaxValueValidator(100)])
I get user input for the value attribute, create an object according to the user input and save it to the database. The problem is that the user can enter e.g. 120 in the form that is used to get the input from the template/html-page to the view's method. Then an invalid object is saved to the database.
How exactly does the MaxValueValidator work? When does it do anything? What purpose do validators serve?( I really couldn't find any answer to my questions in the documentation)
I do check if the input form is valid in the view, but this doesn't seem to prevent saving invalid objects by just changing the HTML attributes in the form via developer tools in the browser
You should use a ModelForm to generate your form from the model if you want your validators to be run automatically. As per docs:
Note that validators will not be run automatically when you save a model, but if you are using a ModelForm, it will run your validators on any fields that are included in your form.
Validators work with Forms
You can make a form, such as
class ObjectForm(forms.Form):
value = forms.IntegerField(validators=[MaxValueValidator(100)])
Then validate the form based on user input
if ObjectForm(request.POST).is_valid():
# save model object here
Hope this helps.

FormView - Specify which fields are sent in the POST

Given a FormView associated to a Form, once the form is submitted some fields are sent to the FormView (those the user has filled).
Question: How can I send to the FormView other fields even if the user didn't fill them (because the fields were already prepopulated)? I need more data than the user provides in order to be used in form_valid
If the data is not sensitive you might want to add them to your form as hidden fields. In django you can achieve this with a FormWidget. There are a few related questions here on SO:
Change a django form field to a hidden field
Django ModelForm to have a hidden input
Be aware that this just hides your data in the user interface, not in the browser - if you are in trouble if someone will change this data in an evil matter, you might consider writing the data in the session.

How to get an auto modified field in django model?

Say I have a model User, which has a credits field (IntegerField). When a user registers, I will set the credits field to 0, and I will update the credits for certain events.
I don't want the user know there is a field like this in the db table.
What attribute should I set to the field?
To accomplish the defaulting to 0 part, you can simply use the default argument of the model field.
For the part where you don't want your users to know about the field, you have a couple choices.
Solution 1: Field.editable
Defining your field as follows will cause the field to never show up in a model form.
credits = models.IntegerField(default=0, editable=False)
Downsides
You won't be able to edit the field's value in the admin
Form validation will never take this field into account (e.g., def clean_credits(self): won't run)
Solution 2: ModelForm.exclude|fields
Creating a ModelForm for the model is something you're going to be doing. You can define an exclude attribute on the form's Meta class, and add "credits" to the list. See the docs linked above. You can instead define fields on the Meta class, and omit "credits". The latter of the two options is considered a better practice, particularly when pertaining to security, and is known as a whitelist.
Downsides
You have to remember to define exclude or fields on every exposed form
Updating the "secret" field
The proper way to handle specifying a "secret" field's value when the field isn't in the form is:
# Inside your view's post method (or FormView.form_valid, if you're using generic views)
instance = form.save(commit=False) # Does everything except INSERT into the database
instance.credits = <however many credits you feel like giving the user>
instance.save()
If you didn't do that, and instead just saved the form as-is, the value specified by default would be set to the instance's credits field.
You'll want to use an IntegerField with default=0: credits = models.IntegerField(default=0). Just take care not to show this field to the user in any forms or when displaying the user.
E.g., if you had a ModelForm for User, do not include credits in the fields field of Meta

django generic view update/create: update works but create raises IntegrityError

I'm using CreateView and UpdateView directely into urls.py of my application whose name is dydict. In the file forms.py I'm using ModelForm and I'm exluding a couple of fields from being shown, some of which should be set when either creating or updating. So, as mentioned in the title, update part works but create part doesn't which is obvious because required fields that I have exluded are sent empty which is not allowed in my case. So the question here is, how should I do to fill exluded fields into the file forms.py so that I don't have to override CreateView?
Thanks in advance.
Well, you have to set your required fields somewhere. If you don't want them to be shown or editable in the form, your options are to set them in the view (by using a custom subclass of CreateView) or if appropriate to your design in the save method of the model class. Or declare an appropriate default value on the field in the model.
It would also work to allow the fields into the form, but set them to use HiddenInput widgets. That's not safe against malicious input, so I wouldn't do that for purely automated fields.
You cannot exclude fields, which are set as required in the model definition. You need to define blank=True/null=True for each of these model fields.
If this doesn't solve your issue, then please show us the model and form definitions, so we know exactly what the code looks like.