2015-12-09 2 views
0

Как ограничить значения, возвращаемые с помощью отношения ManyToMany, и, таким образом, отобразить в поле <SELECT> в моей форме, чтобы показывать только те пятна, которые были созданы в настоящее время вошедшим в систему пользователем?Ограничить выбор, указанный в ManyToMany ForeignKey

models.py

class Project(models.Model): 
    owner = models.ForeignKey(User, editable=False) 
    ... 
    spots = models.ManyToManyField(to='Spot', blank=True,) 

    class Spot(models.Model): 
     owner = models.ForeignKey(User, editable=False) 
     spot_name = models.CharField(max_length=80, blank=False) 

forms.py

from django import forms 
from .models import Project, Spot 


class ProjectForm(forms.ModelForm): 
    class Meta: 
     model = Project 
     exclude = ('owner',) 


class SpotForm(forms.ModelForm): 
    class Meta: 
     model = Spot 
     exclude = ('owner',) 

Я использую GenericViews для обновления и создания и в настоящее время увидеть все записи каждый составил в Пятна, когда я обновляю или создания проекта. Я хочу видеть только записи, введенные зарегистрированным пользователем. Для полноты, да, project.owner и spot.owner были установлены пользователем, когда они были созданы.

Я пробовал def INIT в forms.py и используя limit_choices_to в поле manytomany в модели. Либо я сделал это как неправильно, либо это неправильный способ сделать это.

спасибо!

ответ

1

Как я уже упоминал выше, ответ Дина был очень близко, но не работает для меня. Прежде всего потому, что запрос не доступен непосредственно в представлении. Может быть, это в старых версиях Django? Я на 1.9. Спасибо, Дин, ты забрал меня за горб!

Суть происходящего заключается в том, чтобы добавить пользователя в kwargs в представлении, передав его в ModelForm, удалить пользователя из kwargs и использовать его для фильтрации пятен перед тем, как будет показана форма.

Это код, который работал для моего проекта:

views.py

class ProjectUpdate(UpdateView): 
    model = Project 
    success_url = reverse_lazy('projects-mine') 
    form_class = ProjectForm 

def dispatch(self, *args, **kwargs): 
    return super(ProjectUpdate, self).dispatch(*args, **kwargs) 

def get_form_kwargs(self): 
    kwargs = super(ProjectUpdate, self).get_form_kwargs() 
    kwargs.update({'user': self.request.user}) 
    return kwargs 

forms.py

class ProjectForm(forms.ModelForm): 
    class Meta: 
     model = Project 
     exclude = ('owner', 'whispir_id') 

    def __init__(self, *args, **kwargs): 
     user_id = kwargs.pop('user') 
     super(ProjectForm, self).__init__(*args, **kwargs) 
     self.fields['spots'] = forms.ModelMultipleChoiceField(queryset=Spot.objects.filter(owner=user_id)) 


class SpotForm(forms.ModelForm): 
    class Meta: 
     model = Spot 
     exclude = ('owner',) 

    def __init__(self, *args, **kwargs): 
     user_id = kwargs.pop('user') 
     super(SpotForm, self).__init__(*args, **kwargs) 
     self.fields['spot_name'] = forms.ModelMultipleChoiceField(queryset=Spot.objects.filter(owner=user_id)) 
+0

Я использую 1.8, кстати, вы используете представления на основе классов, поэтому мой метод в views.py не работает так же, как ваш. Но рад видеть, что вы решили проблему. –

1

в вашем forms.py

class ProjectForm(forms.ModelForm): 
    class Meta: 
     model = Project 
     exclude = ('owner',) 

    def __init__(self, user_id, *args, **kwargs): 
     self.fields['spots'] = forms.ModelChoiceField(widget=forms.Select, queryset=Project.objects.filter(owner=user_id)) 


class SpotForm(forms.ModelForm): 
    class Meta: 
     model = Spot 
     exclude = ('owner',) 

    def __init__(self, user_id, *args, **kwargs): 
     self.fields['spot_name'] = forms.ModelChoiceField(widget=forms.Select, queryset=Spot.objects.filter(owner=user_id)) 

в вашем views.py

user_id = Project.objects.get(owner=request.user).owner 
project_form = ProjectForm(user_id) 
spot_form = SpotForm(user_id) 
+0

Я думаю, что мы на разных версиях, потому что ваш ответ Ждут» я работаю для меня, но это было очень близко, и логика была тем, что мне нужно было видеть. Основная проблема заключается в том, что вы не можете получить доступ к объекту запроса, подобному этому в genric view. Вы должны переопределить метод или что-то еще, а затем вы можете получить к нему доступ через self.request. Я отправлю ответ через секунду. – Patrick

Смежные вопросы