pavan kumar
pavan kumar

Reputation: 93

how to limit foreign key choices in the form page?

below are my models, I want to display only those groups in post form in which the user is joined in. Example: if I joined in "mcu" group then only that group should be displayed, how should I do that?? enter image description here

GROUP MODEL

class Group(models.Model):
    name = models.CharField(max_length=200, unique=True)
    description = models.TextField(blank=True, default='')
    members = models.ManyToManyField(User, through='GroupMember')


class GroupMember(models.Model):
    group = models.ForeignKey(Group, related_name='memberships',on_delete=models.CASCADE)
    user = models.ForeignKey(User, related_name='user_groups',on_delete=models.CASCADE)

    class Meta:
        unique_together = ('group', 'user')

POST MODEL

User = get_user_model()

class Post(models.Model):
    user = models.ForeignKey(User, related_name='posts',on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now=True)
    title = models.CharField(max_length=250,default='')
    message = RichTextField()
    group = models.ForeignKey(Group, related_name='posts', null=True, blank=True,on_delete=models.CASCADE)


    class Meta:
        ordering = ['-created_at']
        unique_together = ['user', 'message']

In views.py

class CreatePost(LoginRequiredMixin, SelectRelatedMixin, generic.CreateView):
    model = models.Post
    form_class = forms.PostForm

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.user = self.request.user
        self.object.save()
        return super().form_valid(form)

In forms.py

class PostForm(forms.ModelForm):
    class Meta:
        model = models.Post
        fields = ('title', 'message', 'group')
        widgets = {
            'message': forms.Textarea(attrs={'class': 'form-control mb-3'}),
            'title': forms.TextInput(attrs={'class': 'form-control mb-3'}),
            'group': forms.Select(attrs={'class': 'form-control'}),
        }

Upvotes: 2

Views: 1112

Answers (1)

F A
F A

Reputation: 348

If would've been good if you would've published the views.py of the above form and forms.py where the form is created.

Without seeing the above two files, you would need to perform something like the following.

In your forms.py file, you would have a similar form as below. You need to add def __init__ to add the logic.

Example of the forms.py file-

from django import forms
from django.forms import ModelForm

class PostForm(ModelForm):
    class Meta:
        model = Post
        fields = ['title', 'message', 'group']

    def __init__(self, bundle_seller, *args, **kwargs):
        super(PostForm, self).__init__(*args, **kwargs)
        self.fields['group'].queryset = Group.objects.all().filter(members=loggedin_user)

The reference loggedin_user that you have referred in the last line above needs to be referred in the views.py file for Posts. I'm assuming you're using function-based view in the below example-

def new_post(request):
    ....
    loggedin_user = request.user
    form = PostForm(data=request.POST or None, loggedin_user=loggedin_user)
    if request.method == 'POST':
        ....
    else:
        form = PostForm(loggedin_user=loggedin_user)

Let me know in comments if the above helps.

Upvotes: 4

Related Questions