簡體   English   中英

具有多個模型依賴性的Django ModelForm字段過濾

[英]Django ModelForm Field Filtering with multiple model dependancies

我有成員模型和組模型與成員的外鍵

class Member(models.Model):
    member_name = models.CharField(max_length=100)
    member_dob = models.DateField()

class Group(models.Model):
    group_name = models.CharField(max_length=100)
    group_owner = models.ForeignKey(Member, related_name='owner')
    group_members = models.ManyToManyField(Member, related_name='members')

我創建了另一個模型,Activity,它將引用Group和Member

class Activity(models.Model):
    group_id = models.ForeignKey(Group)
    topic = models.CharField(max_length=100)
    start_by = models.ForeignKey(Member, related_name='started')
    participants = models.ManyToManyField(Member, related_name='participants')

現在我已經為Acivity創建了一個ModelForm

class ActivityForm(ModelForm):
    class Meta:
        model = Activity

如果我在模板中使用了ActivityForm的對象,則所有用戶都將加載到參與者的“選擇”輸入中。 我希望僅顯示屬於選擇選項中顯示的組(具有id = self.group_id)的成員。

有人可以幫我寫一個查詢集,我可以在ActivityForm的init函數中包含這樣做嗎?

如果不是Member有一個外鍵Group 您希望組中的許多成員不是很多,只有一個成員的組?

class Member(models.Model):
    name = models.CharField(max_length=100)
    dob = models.DateField()
    group = modes.ForeignKey('Group', related_name='members')

class Group(models.Model):
    name = models.CharField(max_length=100)
    owner = models.ForeignKey('Member', related_name='owned_groups')

class Activity(models.Model):
    group = models.ForeignKey('Group', related_name='activities')
    topic = models.CharField(max_length=100)
    start_by = models.ForeignKey('Member', related_name='started_activities')
    participants = models.ManyToManyField('Member', related_name='participating_activities')

然后你可以這樣做:

class ActivityForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(ActivityForm, self).__init__(*args, **kwargs)
        if 'initial' in kwargs:
            self.fields['participants'].queryset = Member.objects.filter(group=initial.group)
    class Meta:
        model = Activity

編輯


隨着使用ManyToManyField的更改,我建議您修改字段名稱和相關名稱。 在開發過程的早期進行更改會更容易,而不是在遇到無法修復的其他問題時。 如果它使任何更容易理解只是覺得它是這樣的:相關的名稱將是該模型訪問ForeignKeyManyToManyField點,並且將包含一個queryset有0或多個條目。

所以,如果你有...

class Member(models.Model):
    name = models.CharField(max_length=100)
    dob = models.DateField()

class Group(models.Model):
    name = models.CharField(max_length=100)
    owner = models.ForeignKey('Member', related_name='owned_groups')
    members = models.ManyToManyField('Member', related_name='groups')

class Activity(models.Model):
    group = models.ForeignKey(Group)
    topic = models.CharField(max_length=100)
    start_by = models.ForeignKey('Member', related_name='started_activities')
    participants = models.ManyToManyField('Member', related_name='activities')

那你就可以做......

g1 = Group.objects.create(name='Group 1', ...)
g2 = Group.objects.create(name='Group 2', ...)

member = Member.objects.get(name='John')
member.groups.all() # Get all the groups for the member
member.groups.add(g1, g2) # Add the member to 2 groups
member.activities.all() # Get all activities the member is a participant in
member.started_activities.all() # Get all activities started by the user

而你的表格......

class ActivityForm(ModelForm):
    ...
    def __init__(self, *args, **kwargs):
        super(ActivityForm, self).__init__(*args, **kwargs)
        if 'initial' in kwargs:
            self.fields['participants'].queryset = initial.group.members.all()

    class Meta: 
        model = Activity

我認為這會奏效,但如果沒有:

class ActivityForm(ModelForm):
    ...
    def __init__(self, *args, **kwargs):
        super(ActivityForm, self).__init__(*args, **kwargs)
        if 'initial' in kwargs:
            self.fields['participants'].queryset = Member.objects.filter(group__id=initial.group.id)

    class Meta: 
        model = Activity

您的ActivityForm類需要有一個屬性:

class ActivityForm(ModelForm):
    participants = forms.ModelMultipleChoiceField(queryset=Member.objects.filter(members__id==self.instance.group_id))

你的__init__函數應如下所示:

def __init__(self, *args, **kwargs):
    # call parent
    super(ActivityForm, self).__init__(*args, **kwargs)
    # fill initial values
    self.fields['participants'].initial = [c.pk for c in Member.objects.filter(members__id=self.instance.group_id, participants__in=self.instance)

1)您應該在組中重命名“related_name”。 相關名稱表示如何從其他類中獲知該字段,例如。 來自會員班

2)我認為你的上下文中的“group_members”應該是ManyToManyField。 您的班級組現在允許您只將一個人存儲到一個組中。

命名時可能會出現一些錯誤,因為您的相關名稱非常混亂。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM