Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django model Form. Include fields from related models

I have a model, called Student, which has some fields, and a OneToOne relationship with a user (django.contrib.auth.User).

class Student(models.Model):      phone = models.CharField(max_length = 25 )     birthdate = models.DateField(null=True)      gender = models.CharField(max_length=1,choices = GENDER_CHOICES)      city = models.CharField(max_length = 50)     personalInfo = models.TextField()     user = models.OneToOneField(User,unique=True) 

Then, I have a ModelForm for that model

class StudentForm (forms.ModelForm):     class Meta:         model = Student 

Using the fields attribute in class Meta, I've managed to show only some fields in a template. However, can I indicate which user fields to show?

Something as:

   fields =('personalInfo','user.username') 

is currently not showing anything. Works with only StudentFields though/

Thanks in advance.

like image 775
Tom Avatar asked Sep 27 '09 14:09

Tom


People also ask

How do you exclude a specific field from a ModelForm?

Set the exclude attribute of the ModelForm 's inner Meta class to a list of fields to be excluded from the form.

How do I get form fields in Django?

Basically to extract data from a form field of a form, all you have to do is use the form. is_valid() function along with the form. cleaned_data. get() function, passing in the name of the form field into this function as a parameter.

What is inline formset in Django?

Django formset allows you to edit a collection of the same forms on the same page. It basically allows you to bulk edit a collection of objects at the same time.

What is ModelForm in Django?

Django Model Form It is a class which is used to create an HTML form by using the Model. It is an efficient way to create a form without writing HTML code. Django automatically does it for us to reduce the application development time.


2 Answers

A common practice is to use 2 forms to achieve your goal.

  • A form for the User Model:

    class UserForm(forms.ModelForm):     ... Do stuff if necessary ...     class Meta:         model = User         fields = ('the_fields', 'you_want') 
  • A form for the Student Model:

    class StudentForm (forms.ModelForm):     ... Do other stuff if necessary ...     class Meta:         model = Student         fields = ('the_fields', 'you_want') 
  • Use both those forms in your view (example of usage):

    def register(request):     if request.method == 'POST':         user_form = UserForm(request.POST)         student_form = StudentForm(request.POST)         if user_form.is_valid() and student_form.is_valid():             user_form.save()             student_form.save() 
  • Render the forms together in your template:

    <form action="." method="post">     {% csrf_token %}     {{ user_form.as_p }}     {{ student_form.as_p }}     <input type="submit" value="Submit"> </form> 

Another option would be for you to change the relationship from OneToOne to ForeignKey (this completely depends on you and I just mention it, not recommend it) and use the inline_formsets to achieve the desired outcome.

like image 113
John Moutafis Avatar answered Sep 28 '22 03:09

John Moutafis


Both answers are correct: Inline Formsets make doing this easy.

Be aware, however, that the inline can only go one way: from the model that has the foreign key in it. Without having primary keys in both (bad, since you could then have A -> B and then B -> A2), you cannot have the inline formset in the related_to model.

For instance, if you have a UserProfile class, and want to be able to have these, when shown, have the User object that is related shown as in inline, you will be out of luck.

You can have custom fields on a ModelForm, and use this as a more flexible way, but be aware that it is no longer 'automatic' like a standard ModelForm/inline formset.

like image 26
Matthew Schinckel Avatar answered Sep 28 '22 02:09

Matthew Schinckel