I have created a model Agent that is in a OneToOne relation with the User model. I managed to create a form where I can edit the Agent(user) details, but I would like to populate the form with the existing details of the model(Agent/user). Found something similar here but it is not using Class based views.
models.py ->
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
is_organisor = models.BooleanField(default=True)
is_agent = models.BooleanField(default=False)
class Agent(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
organisation = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
def __str__(self):
return self.user.email
forms.py ->
from django import forms
from django.contrib.auth import get_user_model
User = get_user_model()
class AgentModelForm(forms.ModelForm):
class Meta:
model = User
fields = (
'email',
'username',
'first_name',
'last_name'
)
views.py ->
class AgentUpdateView(OrganisorAndLoginRequiredMixin,generic.UpdateView):
template_name = "agents/agent_update.html"
form_class = AgentModelForm
queryset = Agent.objects.all()
def get_success_url(self):
return reverse("agents:agent_list")
CodePudding user response:
I don't see any advantage in using a OneToOne field. In your case it's better to use a base class (with the User model):
models.py:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
is_organisor = models.BooleanField(default=True)
is_agent = models.BooleanField(default=False)
class Agent(User):
organisation = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
def __str__(self):
return self.email
So, now, 'email', 'username', 'first_name' and 'last_name' are fields of your Agent model.
forms.py
from django import forms
from .models import Agent
class AgentModelForm(forms.ModelForm):
class Meta:
model = Agent
fields = (
'email',
'username',
'first_name',
'last_name'
)
views.py
class AgentUpdateView(OrganisorAndLoginRequiredMixin,generic.UpdateView):
template_name = "agents/agent_update.html"
form_class = AgentModelForm
queryset = Agent.objects.all()
def get_success_url(self):
return reverse("agents:agent_list")
This is call Multi-table inheritance. Each model (User and Agent) corresponds to its own database table and can be queried and created individually. The inheritance relationship introduces links between the child model (Agent) and its parent (User) (via an automatically-created OneToOneField).
More information: https://docs.djangoproject.com/en/dev/topics/db/models/#multi-table-inheritance
CodePudding user response:
There is some confusion in your setup.
The AgentModelForm updates the User model
class AgentModelForm(forms.ModelForm):
class Meta:
model = User
So when your Update view calls its queryset Agent.objects.all()
it can't find the appropriate model in it. So it can't prepopulate the fields.
Despite the view name, if you update the queryset to User.objects.all you might have better luck.
That said, LaCharcaSoftware's answer is probably a less confusing approach that will serve you better going forward.