sikor
sikor

Reputation: 143

django forms - how to filter number of available options in a form

I'm trying to limit number of "categories" that user have available when entering new "feed" only to categories that he owns and he created. The way it works now is that user can add "feed" to other users' "categories" as this is what the form displays. How can I fix it ?

thanks! -M

models.py

from django.db import models
from django.contrib.auth.models import User

class Category(models.Model):
    name = models.CharField(max_length=50)
    user = models.ForeignKey(User)

class Feed(models.Model):
    url = models.URLField()
    name = models.CharField(max_length=50)
    created = models.DateTimeField(auto_now_add=True)
    description = models.TextField(blank=True)
    category = models.ForeignKey(Category)
    user = models.ForeignKey(User)

forms.py

class FeedForm(forms.ModelForm):

    class Meta:
        model = Feed
        exclude = ['user']

views.py

def addfeed(request, user):
    user = request.user
    page_title = "Add feed"
    instance = Category.objects.filter(user=request.user)
    if request.method == 'POST':
        form = FeedForm(request.POST, instance=instance)
        if form.is_valid():
            feed = form.save(commit=False)
            feed.user = request.user  
            feed.save()
            return HttpResponseRedirect("/user/" + user.username + "/manage")
    else:
        form = FeedForm()
    return render(request, "form_manage.html", {
        'page_title': page_title,
        'form': form,
    })

Upvotes: 0

Views: 82

Answers (2)

Peter DeGlopper
Peter DeGlopper

Reputation: 37319

Set the queryset attribute of the field somewhere. Because it depends on your user, it's something you have to set during or after instantiating the form. For instance, here's how to do it in the view:

def addfeed(request, user):
    user = request.user # why does this view take user as an arg and then reassign?
    page_title = "Add feed"
    categories = Category.objects.filter(user=request.user)
    if request.method == 'POST':
        form = FeedForm(request.POST)
        form.fields['category'].queryset = categories
        if form.is_valid():
            feed = form.save(commit=False)
            feed.user = request.user  
            feed.save()
            return HttpResponseRedirect("/user/" + user.username + "/manage")
    else:
        form = FeedForm()
        form.fields['category'].queryset = categories
    return render(request, "form_manage.html", {
        'page_title': page_title,
        'form': form,})

I removed the instance argument to your POST case's form construction because that's meant for passing in an existing Feed instance, not a categories queryset.

You could also do this in the form's __init__ if you pass in the correct categories queryset.

Upvotes: 1

Garry Cairns
Garry Cairns

Reputation: 3115

I use javascript to do this. For example, you could pass a list of the relevant categories as extra context in your view then use javascript in your template to empty the pre-populated option field in the form and replace it with your extra context.

Upvotes: 0

Related Questions