Reputation: 67
How to I bind User fields data and user profile data to a model form on my view, I only get user data rendered to a form when i use instance=user but it doesn't render any data of user profile on instance=profile, what i need is to render all user and its profile to a form.
models.py
class User(AbstractUser):
is_supervisor = models.BooleanField(default=False)
is_student = models.BooleanField(default=False)
class Supervisor(models.Model):
user = models.OneToOneField('User', on_delete=models.CASCADE, primary_key=True, related_name='supervisor')
su_mobile_number = models.CharField(max_length=200)
view.py
def supervisor_update(request, user_id):
# user = get_object_or_404(User, pk=user_id)
user = get_object_or_404(User, pk=user_id)
profile = get_object_or_404(Supervisor, pk=user_id)
if request.method == 'POST':
form = SupervisorSignUpForm(request.POST, instance=user)
else:
form = SupervisorSignUpForm(instance=user)
return save_user_form(request, form, 'partials/partial_supervisor_update.html')
form.py
class SupervisorSignUpForm(UserCreationForm):
su_mobile_number = forms.CharField(label="Mobile Number")
class Meta(UserCreationForm.Meta):
model = User
fields = ('username', 'email', 'password1', 'password2', 'first_name', 'last_name')
supervisor_update.html
{% load crispy_forms_tags %}
<form method="post" action="{% url 'supervisor_update' form.instance.pk %}" class="js-supervisor-update-form">
{% csrf_token %}
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">Update Supervisor</h4>
</div>
<div class="modal-body">
{% include 'partials/form_messages.html' %}
{{ form.username|as_crispy_field }}
{{ form.email|as_crispy_field }}
{{ form.first_name|as_crispy_field }}
{{ form.last_name|as_crispy_field }}
{{ form.su_mobile_number|as_crispy_field }}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Update Supervisor</button>
</div>
</form>
Upvotes: 0
Views: 266
Reputation: 715
To set the extra field passing in initial along with the user instance should work
initial = {'su_mobile_number': profile.su_mobile_number}
form = SupervisorSignUpForm(instance=user, initial=initial)
Or if you dont want to manually create the dict you could use model_to_dict
from django.forms.models import model_to_dict
initial = model_to_dict(profile, exclude=['user'])
form = SupervisorSignUpForm(instance=user, initial=initial)
Also at the top of your view you are assuming user and supervisor have the same id which could not be the case instead you could do something like this
user = user = get_object_or_404(User, pk=user_id)
profile = user.supervisor
if not profile:
raise Http404
Upvotes: 1