Использование профиля пользователя для автоматической загрузки информации в поля формы

В своем предыдущем вопросе я спросил, как я могу автоматически сохранить пользователя, отправляющего форму. Я нашел метод form_valid наилучшим в этом случае. Однако в моих моделях у меня также есть модель профиля пользователя, подобная этой

models.py

....
class Profile(models.Model):
  user = models.OneToOneField(User,on_delete=models.CASCADE)
  title = models.CharField(max_length=24)
  first_name = models.CharField(max_length=35)
  last_name = models.CharField(max_length=35)
  email = models.EmailField(max_length=64)
  phone_number = models.CharField(max_length=12)
  department = models.ForeignKey(Department,null=True,on_delete=models.SET_NULL)
  supervisor = models.ForeignKey('self',blank=True,null=True,on_delete=models.SET_NULL)
...

Как вы видите, я использовал метод One to One для создания своего UserProfile

Как и раньше в моем models.py у меня есть модель отчетов

...
class Report(models.Model):
  id = models.UUIDField(primary_key=True,default=uuid.uuid1,editable=False)
  department = models.ForeignKey(Company,null=True,on_delete=models.SET_NULL)
  user= models.ForeignKey(User,on_delete=models.PROTECT)
  submission_date= models.DateField(auto_now=True) #invisible to user
  submission_time = models.TimeField(auto_now=True) #invisible to ,user
  date = models.DateField(default=now,blank=False)
  time = models.TimeField(default=now,blank=False,help_text="hh:mm:ss")
  location = PlainLocationField()
  building = models.ForeignKey(bld,null=True,on_delete=models.SET_NULL)
  size = models.PositiveIntegerField()
  notes = models.TextField(blank=True)
   def __str__(self):
     return f'{self.date} {self.time} ({self.department})
...

Мой вопрос, как я могу сделать так, чтобы поле отдела загружалось из профиля пользователя? Я надеюсь в конечном итоге сделать так, чтобы пользователи одного отдела могли просматривать и обновлять отчеты друг друга.

Как и раньше:

form.py

class ReportForm(forms.ModelForm):
    class Meta:
        model = Report
        fields = '__all__'
        location = PlainLocationField()
    def redirect():
        return redirect("Report")

views.py

class ReportCreate(LoginRequiredMixin,CreateView):
    Template = "templates\reports\Report.html"
    model = Report
    fields = '__all__'
    def form_valid(self, form):
        form.instance.user = self.request.user
        form.instance.save()
        return super(ReportCreate, self).form_valid(form)
    def get_success_url(self):
        return reverse('Report')
    def get_absolute_url(self):
        return reverse('Report', kwargs={'pk':self.pk})

Вот несколько шагов, которые помогут вам автозаполнить некоторые поля:

  1. Получение пользователя из self.request.user. Как получить доступ к текущему пользователю в представлении на основе класса в Django
  2. Получение профиля: get user profile in django
  3. Передайте необходимые поля как контекстные переменные: https://www.geeksforgeeks.org/how-to-pass-additional-context-into-a-class-based-view-django/
  4. .
  5. Передайте это в javascript. Как я могу передать мои контекстные переменные в файл javascript в Django?
  6. .
  7. Установите значение следующим образом: Установите значение поля ввода
  8. .

СДЕЛАНО!

Советую вам использовать related_name в вашей ForeignKeys. Установите поле department обеих моделей следующим образом:

class Profile(models.Model):
    ...
    department = models.ForeignKey(Department, null=True, on_delete=models.SET_NULL, related_name='profiles')
    ...

class Report(models.Model):
    ...
    department = models.ForeignKey(Department, null=True, on_delete=models.SET_NULL, related_name='reports')
    ...

Отныне к объектам Department, связанным с User.Profile, можно обращаться так:

Department.profiles.all()           # it returns QuerySet of all related to Department Profile objects
Department.reports.all()            # it returns QuerySet of all related to Department Report objects

И вы можете использовать его при создании QuerySet для пользователя:

Report.objects.filter(department=self.request.user.profile.department)
# it returns all Report objects, that have exactly the same department as the user

Или используя наши новые отношения:

department = self.request.user.profile.department
reports_for_user = department.reports.all()

Но я вижу одну проблему. Вы используете модель Company для ForeignKey в отчете. Это должна быть одна и та же модель Department для обеих моделей Profile и Report, чтобы такой простой вариант работал. Также вам определенно не следует смешивать именование в одном проекте. Вы можете установить связь с Company в качестве другого поля:

company = models.ForeignKey(Company, null=True, on_delete=models.SET_NULL)
Вернуться на верх