代码之家  ›  专栏  ›  技术社区  ›  Felix

筛选用于窗体的django用户选择字段

  •  0
  • Felix  · 技术社区  · 8 年前

    我正在做一个艰苦的django项目,我又陷入了困境。我在用户配置文件中有一个字段,叫做force:

    class UserProfile(models.Model):
    
        scout_username = models.OneToOneField(User, on_delete=models.CASCADE)
        Group_Choice = Groups.Scout_Groups()
        troop = models.SlugField(max_length=27, choices=Group_Choice, default='None', blank=False)
        date_of_birth = models.DateField(default=date.today)
    
    
        def __str__(self):
            return '%s'% (self.scout_username)
    
    def create_profile(sender, **kwargs):
        if kwargs['created']:
            user_profile = UserProfile.objects.create(user=kwargs['instance'])
    
    post_save.connect(create_profile, sender=User)
    

    然后我有一个填写数据的表单,它被发送到我的stdata模型。在表单中,用户可以选择添加有关其他用户的详细信息。但是他们只能将详细信息添加到具有相同 troop 细节。 表单.py

    from django import forms
    from leaders.models import stData
    from django.contrib.auth.models import User
    from accounts.models import UserProfileManager, UserProfile
    
    st_username_list=[
        (None, 'Choose a user'),
        (user1, 'user1'),
        (i, 'no progress'),
        ]
    
    class BadgeForm(forms.ModelForm):
        def set_user(self, user):
            global st_username_list
            troop = user.userprofile.troop
            userprofile = UserProfile.objects.all()
            selected_st = userprofile.filter(troop=troop)
            for st in selected_st:
                username = str(st.st_username)
                st_username_list.append((username, username))
        st_username = forms.ChoiceField(choices=st_username_list)
        class Meta:
            model = stData
            fields = ('st_username', 'Pioneer_Badge', 'Explorer_Badge', 'Adventurer_Badge', 'Proficiency_Badge', 'Other_Badge') 
    

    请注意 在上面的例子中,我使用了一个全局变量。我知道这是远远不够的。由于解释了正确的过滤方法(在断线后发现),我已经移除了它。我保留这个只是为了教育的原因,其他人可能会发现他们有类似的问题。

    我在我的视图中通过用户,如下所示:

    user = request.user
    user_form_setting = BadgeForm.set_user(self, user)
    

    模型.py

    from django.db import models
    from django.contrib.auth.models import User
    
    from accounts.st_badge_list import st_List
    
    class stData(models.Model):
    
        Pioneer_Choices = st_List.Target_Badges()
        Blue_Choices = st_List.Target_Badges()
        Black_Choices = st_List.Target_Badges()
        Proficiency_Choices = st_List.Proficiency_Badges()
        Other_Choice = st_List.Other_Badges()
    
        Pioneer_Badge = models.CharField(max_length=16, choices=Pioneer_Choices, default='None', blank=True)
        Blue_Star = models.CharField(max_length=16, choices=Blue_Choices, default='None', blank=True)
        Black_Star = models.CharField(max_length=16, choices=Black_Choices, default='None', blank=True)
        Proficiency_Badge = models.CharField(max_length=22, choices=Proficiency_Choices, default='None', blank=True)
        Other_Badge = models.CharField(max_length=27, choices=Other_Choice, default='None', blank=True)
    
    
        st_username = models.ForeignKey(User, on_delete=models.CASCADE)
        date = models.DateTimeField(auto_now=True)
        print (User)
    
        def __str__(self):
            return '%s'% (self.st_username)
    

    我怎样才能拥有它,这样无论什么用户都有相同的 队伍 详细信息将作为一个选项出现在st_username_列表中? 在对代码进行研究和尝试之后,我发现: ValueError Cannot assign "'user1'": "stData.st_username" must be a "User" instance. 我希望这不会太混乱。


    编辑 好的,我发现我可以通过

    def __init__(self, *args, **kwargs):
    
            super().__init__(*args, **kwargs)
            self.fields['st_username'].queryset = UserProfile.objects.filter(troop='''user's troop''')
    

    问题更新 我现在的主要问题是无法通过模型中的用户实例。我见过这个 question here . 所以我把这个加入到我的表格的innit方法中:

        self.user = kwargs.pop('user')
    

    但是当我试图通过 self.user 我得到一个无用的错误键错误说 user . 外壳显示这可能是由于 self.user = kwargs.pop(user) 我相信这可能是因为我没有通过用户。所以当我在视图中调用表单时,我尝试 form = BadgeForm(user=request.user) 同样的错误。

    我的Queryset现在看起来是这样的:

    self.fields['scout_username'].queryset=UserProfile.objects.filter(troop=user.userprofile.troop)
    

    更多信息: 为了更好地理解这个问题,我在queryset中传递了一个部队的set变量。所以在这种情况下

    self.fields['scout_username'].queryset=UserProfile.objects.filter(troop='BC')
    

    尽管现在我得到了错误属性错误: “BadgeForm”对象没有属性' 名称 ’ shell将此与我使用表单的表单集链接起来。我得到的详细信息是:

    line 435, in formset_factory
        return type(form.__name__ + 'FormSet', (formset,), attrs)
    

    我希望这对你比我更有意义!任何帮助都将不胜感激!

    1 回复  |  直到 8 年前
        1
  •  1
  •   Felix    8 年前

    最后一个问题是表单集的使用。 根据 docs ,添加kwargs的正确方法是:

        BadgeFormsSet = formset_factory(BadgeForm)
        formset = BadgeFormsSet(form_kwargs={'user': request.user})
    

    希望这对任何人都有帮助!