Доступ к полю из поля OneToOne в ModelForm с помощью представлений на основе классов
Я создал модель Agent, которая находится в отношении OneToOne с моделью User. Мне удалось создать форму, в которой я могу редактировать данные агента (пользователя), но я хотел бы заполнить форму существующими данными модели (агент/пользователь). Нашел что-то похожее здесь, но там не используются представления на основе классов.
models.py ->
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")
Я не вижу никаких преимуществ в использовании поля OneToOne. В вашем случае лучше использовать базовый класс (с моделью User):
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
Итак, теперь 'email', 'username', 'first_name' и 'last_name' являются полями вашей модели агента.
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")
Это называется многотабличным наследованием. Каждая модель (Пользователь и Агент) соответствует своей собственной таблице базы данных и может быть запрошена и создана индивидуально. Отношения наследования вводят связи между дочерней моделью (Agent) и ее родителем (User) (через автоматически создаваемое поле OneToOneField).
Дополнительная информация: https://docs.djangoproject.com/en/dev/topics/db/models/#multi-table-inheritance
В вашей настройке есть некоторая путаница.
Форма AgentModelForm обновляет модель User
class AgentModelForm(forms.ModelForm):
class Meta:
model = User
Поэтому, когда ваше представление Update вызывает свой queryset Agent.objects.all()
, оно не может найти в нем соответствующую модель. Поэтому оно не может предварительно заполнить поля.
Несмотря на имя представления, если вы обновите набор запросов до User.objects.all, вам может повезти больше.
Тем не менее, ответ LaCharcaSoftware, вероятно, является менее запутанным подходом, который будет лучше служить вам в дальнейшем.