Опция исключения в выборе, который уже выбран пользователем - PullRequest
2 голосов
/ 12 февраля 2020

Можно ли исключить опции, которые уже выбраны пользователем и сохранены в таблице?

Это таблицы из моделей .py

class Fruit(models.Model):
name = models.CharField(max_length=250, unique=True, blank=False, null=False)
sort= models.ForeignKey('FruitSort', on_delete=models.SET_NULL, null=True, blank=False)

def __str__(self):
    return '%s (%s)' % (self.name, self.sort.name)

class UserFruit(models.Model):
    Comment = models.CharField(max_length=55)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    fruit = models.ForeignKey('Fruit', on_delete=models.CASCADE)

    class Meta:
        unique_together = (("user", "fruit",),)

Это формы. Py, которая генерирует мою форму.

class UserFruit(forms.ModelForm):

class Meta:
    model = UserFruit
    fields = ('comment', 'fruit')

def __init__(self, *args, **kwargs):
    super(UserFruit, self).__init__(*args, **kwargs)
    for visible in self.visible_fields():
        visible.field.widget.attrs['class'] = 'form-control form-style-alt'
        self.fields['comment'].widget.attrs['placeholder'] = 'comment'
        self.fields['fruit'].empty_label = 'Please, choose fruit'

Теперь views.py

class Fruit(generic.CreateView):
    form_class = UserFruit
    template_name = 'fruit.html'

    def get(self, request, *args, **kwargs):
        form = self.form_class(instance=UserFruit.objects.filter(user=request.user).first())
        fruit = UserFruit.objects.filter(user=request.user)
        return render(request, self.template_name, {'form': form, 'fruit': fruit})

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.user = request.user
            post.save()
        return redirect('fruit')

И, наконец, шаблон.

 <h3>Add a juicy fruit</h3>
        <form method="post">
            {% csrf_token %}
                <div class="form-group">
                    <div>
                        <span class="text-danger">{{ error }}</span>
                    </div>
                {{ form.fruit }}
                {{ form.comment }}
                    <button class="btn" type="submit"> Save</button>
                </div>
        </form>

Я хочу исключить или отключить Фрукты, которые пользователь уже добавил. Кажется, я не нахожу DRY и гладкого решения для этого. Я могу l oop пройти из базы данных и исключить через javascript. Но кажется липким.

Идеи очень ценятся!

1 Ответ

3 голосов
/ 12 февраля 2020

Да . Например, вы можете передать параметр user в форму, и в качестве набора запросов выберите Fruit s, который еще не выбран, например:

class <b>UserFruitForm</b>(forms.ModelForm):

    class Meta:
        model = UserFruit
        fields = ('comment', 'fruit')

    def __init__(self, <b>user</b>, *args, **kwargs):
        super(UserFruit, self).__init__(*args, **kwargs)
        for visible in self.visible_fields():
            visible.field.widget.attrs['class'] = 'form-control form-style-alt'
        self.fields['comment'].widget.attrs['placeholder'] = 'comment'
        self.fields['fruit'].empty_label = 'Please, choose fruit'
        self.fields['fruit'].queryset = Fruit.objects.<b>exclude(
            userfruit__user=user
        )</b>

Однако вы делаете слишком много в вашем CreateView. Вы можете просто позволить CreateView выполнять почти всю работу с:

from django.urls import reverse_lazy

class Fruit(generic.CreateView):
    form_class = <b>UserFruitForm</b>
    template_name = 'fruit.html'
    success_url = reverse_lazy('fuit')

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs.update(<b>user=self.request.user</b>)
        return kwargs

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        context.update(fruit=UserFruit.objects.filter(user=self.request.user))
        return context

    def form_valid(self, form):
        form.instance.user = self.request.user
        super().form_valid(form)

Пожалуйста, переименуйте форму в UserFruitForm. Прямо сейчас вы вводите имя cla sh между моделью UserFruit и формой UserFruit. Переименовав его, становится понятно, на что вы ссылаетесь.

...