3

How to reduce the foreign key data to a subset related to current object? For example:

from django.db import models

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    # Not correct, it display the choices of all questions on not only
    # the choices of the current question
    answer = models.ForeignKey('Choice', related_name='question_related_choices')


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

The answer field should contain only the choices of the related question and not the choices of all question.

I tried to use limit_choice_to of django without success. I think this is the best way to solve the problem to select a single correct choice for each section.

I also thought about using a field in Choice model, and display it as a radio button.. but I don't know how to achieve this. Thanks for the support.

I found a similar problem but I'm not able to figure out that solution, even because it use threads and so on... How do I restrict foreign keys choices to related objects only in django

Edit 1:

I'm still struggling with this problem, but probably I found the right direction. I found this discussion: https://stackoverflow.com/a/4656296/2653437 and the last answer seems the right one:"This limiting of choices to current user is a kind of validation that needs to happen dynamically in the request cycle, not in the static Model definition." Using threadlocals middleware to store data probably is not the right approach to this problem, instead, limiting the choices in the form seems more simple and clear.

If I figured out well, as show here: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin.form django admin, allow to specify a custom modelform. By default django admin use the ModelForm, M --> F, but to limiting the choice we can inherit from and add/edit custom fields: M --> CMF -- F

forms.py

class AnswerForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(Question, self).__init__(*args, **kwargs)
        self.fields['answer'].queryset = Choice.objects.filter(question__choice=self)

    class Meta:
        fields = '__all__'
        model = Question

admin.py

class QuestionAdmin(admin.ModelAdmin):
    form = AnswerForm
    list_display = ('question_text', 'pub_date', 'was_published_recently')
    fieldsets = [
        (None,               {'fields': ['question_text']}),
        (None,               {'fields': ['answer']}),
        ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
    ]
    inlines = [ChoiceInline]

But the problem is still to get the instance of question to filtering/query the choice. Currently I get the following error:

TypeError: super(type, obj): obj must be an instance or subtype of type
[15/Aug/2016 11:50:34] "GET /admin/polls/question/3/change/ HTTP/1.1" 500 1260

Any suggestion/advice or a correct answer will be highly appreciated

Edit 2:

From the traceback I saw there's the key 'instance' in kwargs. This is the key because with it you can limit the choices only to related question with:

self.fields['answer'].queryset = Choice.objects.filter(question=kwargs['instance'])
Community
  • 1
  • 1
realnot
  • 721
  • 1
  • 11
  • 31

0 Answers0