Доступ к полю из поля 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, вероятно, является менее запутанным подходом, который будет лучше служить вам в дальнейшем.

Вернуться на верх