0

When showing a CreateView form I would like to fill a foreignKey value using data from the logged in user. I want this to be read only.

My models are:

# User profile info
class Profile(models.Model):

    # Relationship Fields
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    school = models.ForeignKey('eduly.School', default=1)

    notes = models.TextField(max_length=500, blank=True)


@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)


@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()


class School(models.Model):

    # Fields
    name = models.CharField(max_length=255)
    address = models.TextField(max_length=500, blank=True)
    email = models.CharField(max_length=30)
    phone = models.CharField(max_length=15)
    contactName = models.CharField(max_length=30)
    slug = extension_fields.AutoSlugField(populate_from='name', blank=True)
    created = models.DateTimeField(auto_now_add=True, editable=False)
    last_updated = models.DateTimeField(auto_now=True, editable=False)


    class Meta:
        ordering = ('-created',)

    def __unicode__(self):
        return u'%s' % self.slug

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('eduly_school_detail', args=(self.slug,))


    def get_update_url(self):
        return reverse('eduly_school_update', args=(self.slug,))


class Teacher(models.Model):

    SCHOOL_ADMIN = 0
    CLASS_ADMIN = 1
    TASK_ADMIN = 2

    ROLES = {
        (SCHOOL_ADMIN, "School administrator"),
        (CLASS_ADMIN, "Class administrator"),
        (TASK_ADMIN, "Task administrator")
    }

    # Fields
    name = models.CharField(max_length=255)
    slug = extension_fields.AutoSlugField(populate_from='name', blank=True)
    created = models.DateTimeField(auto_now_add=True, editable=False)
    last_updated = models.DateTimeField(auto_now=True, editable=False)
    email = models.CharField(max_length=30)
    roles = models.IntegerField("Role", choices=ROLES, default=1)

    # Relationship Fields
    school = models.ForeignKey('eduly.School', )

    class Meta:
        ordering = ('-created',)

    def __str__(self):
        return self.name

    def __unicode__(self):
        return u'%s' % self.slug

    def get_absolute_url(self):
        return reverse('eduly_teacher_detail', args=(self.slug,))


    def get_update_url(self):
        return reverse('eduly_teacher_update', args=(self.slug,))

My views are:

@method_decorator(login_required, name='dispatch')
class TeacherListView(ListView):
    model = Teacher

    def get_queryset(self):
        return Teacher.objects.filter(school=self.request.user.profile.school)


@method_decorator(login_required, name='dispatch')
class TeacherCreateView(CreateView):
    model = Teacher
    form_class = TeacherForm

For the TeacherCreateView I want to set the Teacher.school foreignKey field to self.request.user.profile.school with the field read only.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
Bill Noble
  • 6,466
  • 19
  • 74
  • 133
  • This will help you https://stackoverflow.com/questions/32273135/how-to-override-form-field-in-createview – itzMEonTV Nov 10 '17 at 15:12
  • I am not sure how that answer relates to setting a foreignKey field and making it read only? – Bill Noble Nov 10 '17 at 15:16
  • Why do you want to make it read-only, specifically? If the user can't modify it, why bother displaying it at all? Just set it in the view, see [here](https://docs.djangoproject.com/en/1.11/topics/class-based-views/generic-editing/#models-and-request-user) for an example of how to do that. – Daniel Roseman Nov 10 '17 at 16:10
  • Hi, i am not good at HTML so if you know how to do this with HTML using styles and classes i can tell you how to add a class or style to a widget from the create view :) – mohammedgqudah Nov 10 '17 at 16:29
  • @DanielRoseman for the moment, while developing the code, I want to show the school name when the teacher, and other forms are shown. I have tried the example you pointed to and that works great though – Bill Noble Nov 10 '17 at 16:37

1 Answers1

0

In your form you can do like below. The magic is with field attribute disabled.

class TeacherForm(forms.modelForm):
    def __init__(self, *args, **kwargs):
        super(TeacherForm, self).__init__(*args, **kwargs)
        self.fields['school'].disabled = True

    class Meta:
       fields = '__all__'

You can read it django docs. Reference: https://docs.djangoproject.com/en/1.11/ref/forms/fields/#disabled

Evan
  • 1,960
  • 4
  • 26
  • 54
anjaneyulubatta505
  • 10,713
  • 1
  • 52
  • 62