Фильтрация Django User Choice Использование поля для формы - PullRequest
0 голосов
/ 03 июня 2018

Я работаю над жестким проектом Django и снова застрял.У меня есть поле в профиле пользователя, которое называется troop:

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 данные.forms.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)

models.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)

Как мне поступить так, чтобы у любого пользователя были такие же troop данные, которые отображались бы в списке st_username_list как выбор?После исследования и проб с кодом я получил: ValueError Cannot assign "'user1'": "stData.st_username" must be a "User" instance. Надеюсь, это не слишком запутанно.


Редактировать Хорошо, поэтому я обнаружил, что могу фильтроватьпараметры для st_username, выполнив

def __init__(self, *args, **kwargs):

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

Обновление проблемы Моя главная проблема сейчас заключается в том, что я не могу пройти через пользовательский экземпляр в модели.Я видел этот вопрос здесь .Поэтому я добавил это к методу innit моей формы:

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

Тем не менее, когда я пытаюсь использовать пользователя, набрав self.user, я получаю бесполезную ошибку KeyError, говорящую user.Оболочка указала, что это может быть связано с self.user = kwargs.pop(user) Я полагаю, что это может быть из-за того, что я не проходил через пользователя.Поэтому, когда я вызываю форму в своих представлениях, я пытался form = BadgeForm(user=request.user) и получал ту же ошибку.

мой набор запросов теперь выглядит следующим образом:

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

Дополнительная информация: Чтобы лучше понять проблему, я прошел через переменную set группы в наборе запросов.Так что в этом случае

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

Хотя теперь я получаю сообщение об ошибке AttributeError: у объекта 'BadgeForm' нет атрибута ' name ' Оболочка связывает это с набором форм, из которого я использую форму с,Детали, которые я предоставил:

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

Надеюсь, это имеет больше смысла для вас, чем для меня!Любая помощь будет принята с благодарностью!

1 Ответ

0 голосов
/ 04 июня 2018

Последняя проблема была в использовании formset.Согласно docs , правильный способ добавить kwargs заключается в следующем:

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

Надеюсь, это поможет кому-то еще!

...