ceaess
ceaess

Reputation: 68

Limiting Form Options Based on Relation to Logged In User

I've found several solutions for doing this on the admin page or dynamically filtering using javascript based on another field, but I can't seem to piece the thoughts on those topics together to fix what I want.

I have the following:

I want:

Code:

Models.py:

    class SunshineUser(AbstractBaseUser):
        email = models.EmailField(
            verbose_name='email address',
            max_length=320, 
            unique=True
            )

        USERNAME_FIELD = 'email'

        name = models.CharField(max_length=150)

        is_active = models.BooleanField(default=True)

        is_admin = models.BooleanField(default=False)

        REQUIRED_FIELDS = ['name']

        objects = SunshineUserManager()

        def get_full_name(self):
            # The user is identified by their email address
            return self.email

        def get_short_name(self):
            # The user is identified by their name
            return self.name

        def __str__(self):
            return self.email

        def has_perm(self, perm, obj=None):
            return True

        def has_module_perms(self, app_label):
            return True

        @property
        def is_staff(self):
            return self.is_admin

    class Sunshine(models.Model):
        user = models.ForeignKey(settings.AUTH_USER_MODEL)
        label = models.CharField(max_length=150)
        SUNSHINE_TYPES = (
            ('R', 'Rain'),
            ('SH', 'Shine'),
            ('C', 'Clouds')
        )
        sunshine_type = models.CharField(max_length=2, choices=METER_TYPES)
        POSSIBLE_UNITS = (
            ('CCF', 'Hundreds of Cubic Feet'),
            ('GAL', 'Gallons')
        )
        units = models.CharField(max_length=3, choices=POSSIBLE_UNITS)

        def get_full_name(self):
            return self.label

        def get_short_name(self):
            return self.label

        def __str__(self):
            return self.label


    class Ray(models.Model):

        sunshine = models.ForeignKey(Sunshine)
        ray_amount = models.DecimalField(max_digits=15, decimal_places=5,
         validators=[MinValueValidator(0)])
        timestamp = models.DateTimeField()

        def get_full_name(self):
            return self.timestamp

        def get_short_name(self):
            return self.timestamp

        def __str__(self):
            return self.timestamp

Views.py:

def addray(request):
"""
processing for addreading
"""
if request.method == "POST":
    form = RayCreationForm(request.POST)
    if form.is_valid():
        form.save()
        # redirect, or however you want to get to the main view
        return HttpResponseRedirect('/personal/dashboard')
else:
    form = RayCreationForm()
    #form.sunshine.queryset = Sunshine.objects.filter(user_id=request.user.id)

return render(request, 'personal/addray.html', {'form': form})

Forms.py:

All I have right now is a basic form, because I've tried the commented out line under else in the views and a few other things and nothing has worked.

class RayCreationForm(forms.ModelForm):
class Meta:
    model = Ray
    fields = ['sunshine', 'ray_amount', 'timestamp']

Upvotes: 2

Views: 174

Answers (1)

Pratyush
Pratyush

Reputation: 5498

In else, instead of the commented out line, you can try:

form.fields['sunshine'].queryset = Sunshine.objects.filter(user_id=request.user.id)

Other ways of filtering an initial queryset in a ModelChoiceField are shared here: https://stackoverflow.com/a/5329761/232649

Upvotes: 2

Related Questions