Django modelformset exclude - django

Lets say I have a model with 2 fields: user and money. And I want to edit only users money fields.
If i create a modelformset and exclude for example user field from the form, then does it mean that if someone creates a false form, with user field included it will ignore it and save with bounded instance?
Or do i still need to validate something like this? And if, for example, someone still includes new form with new user in it how do I go about it?

Related

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.

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

How to render a ForeignKey field as CharField in Django forms

My Model
class Collaborator(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
My Form:
class CollaboratorForm(forms.ModelForm):
user = forms.CharField(max_length=30, required=False)
class Meta:
model = Collaborator
fields = ('user',)
The template render the user input text as an autocomplete field loaded from User model.
The page shows the user input text field correctly, however when I go to edit a Collaborator the user input text field shows the user Id and I want to show the username instead.
You want to figure out first what the exact behavior you want is.
Let's say I'm user with id=1, username="Joel". When you produce your CollaboratorForm and it shows "Joel" (my username) on the form and you edit it to read "Jane", are you:
trying to edit my name to "Jane", so that id=1 now has a username=Jane ?
or trying to change the associated user to the user matching that username?
Once you know that, you can proceed.
I'd change the user = forms.CharField(..) to username = forms.CharField(..); that's what your really showing, after all.
In your view, when you create your form, pass it the initial values of {'username':username-of-user-that-is-currently-related}.
In your view, when you process the form, before you save it, use the cleaned_data['username'] to either (a) update the username of that user (if the first case above) or (b) get the ID of the new user and save that to the .user field (if the second case above).
Of course, if what you want is really at a higher-level "let people pick the user based on the username", you might be able to solve this differently and more easily--by not using a CharField at all, and using a ChoiceField instead, so you could show a drop down menu of users with the key=ID and value=name. Depending on how many users you have, though, that might not scale well.

Updating user information for an extend user field - 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

django forms doubt

Here, I am a bit confused with forms in Django. I have information for the form(a poll i.e the poll question and options) coming from some db_table - table1 or say class1 in models. Now the vote from this poll is to be captured which is another model say class2. So, I am just getting confused with the whole flow of forms, here i think. How will the data be captured into the class2 table?
I was trying something like this.
def blah1()
get_data_from_db_table_1()
x = blah2Form()
render_to_response(blah.html,{...})
Forms have nothing to do with models in Django. They are just class meant to get informations from a dictionary (often request.POST) and check if each data linked to a key match a type and a format (e.g: is this a string of the form "bla#foo.tld").
You can ask django to create a form from a model, and in that case it will do its checking job, then if the data match, it will create a model, fill it and save it.
If a form is not created from a model, it will do nothing but checking. It will save nothing.
If it is created from a model, it will create a new instance of this particular model instance and save it.
If you want something more complicated, like, pre fill a form from various models or according to some conditions, or, say, you need to save several models according to the result of one form, you must do it manually.