Django限制外键选项

时间:2020-05-15 03:08:40

标签: django django-models

所以我有三种模型:

class Session(models.Model):
    id = models.UUIDField('ID', default=uuid.uuid4, primary_key=True, editable=False)
    start_time = models.TimeField('Start Time', default=None)
    end_time = models.TimeField('End Time', default=None)

    def __str__(self):
        return "{}-{}".format(str(self.start_time), str(self.end_time))


class Slot(models.Model):
    id = models.UUIDField('ID', default=uuid.uuid4, primary_key=True, editable=False)
    timings = models.ForeignKey('Session', on_delete=models.DO_NOTHING, related_name='slot_timings')
    available_counsellors = models.ManyToManyField(User, limit_choices_to={'role': 'COUNSELLOR'}, related_name='available_counsellors')

    def __str__(self):
        return str(self.timings)


class ChatSession(models.Model):

    def get_access_code():
        while True:
            access_code = get_random_string(length=6, allowed_chars=('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'))
            if not ChatSession.objects.filter(access_code=access_code).exists():
                return access_code

    id = models.UUIDField('ID', default=uuid.uuid4, primary_key=True, editable=False)
    client = models.ForeignKey(User, limit_choices_to={'role': 'CLIENT'}, on_delete=models.DO_NOTHING, related_name='client_user')
    counsellor = models.ForeignKey(User, limit_choices_to={'role': 'COUNSELLOR'}, on_delete=models.DO_NOTHING, related_name='counsellor_user')
    access_code = models.CharField('Access Code', default=get_access_code, max_length=6)
    topic = models.CharField('Topic', default=None, blank=True, null=True, max_length=255)
    slot = models.ForeignKey(Slot, on_delete=models.DO_NOTHING, default=None)

    def __str__(self):
        return str(self.topic)

在聊天会话模型中,我想将辅导员字段的选项限制为插槽模型中的available_counsellors列表。 我该怎么做?

我也希望在管理员视图中也能体现出同样的意思。

1 个答案:

答案 0 :(得分:0)

您需要更新queryset表单字段上的counsellor

假设您正在使用ModelForm,则可以在视图中执行此操作:

chat_session = ChatSession.objects.get(pk=1)
form = ChatSessionForm(instance=chat_session)
form.fields["counsellor"].queryset = chat_session.slot.available_counsellors

您也可以在ModelForm中完成它:

class ChatSessionForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super (ChatSessionForm, self).__init__(*args, **kwargs)
        if self.instance and self.instance.slot:
            options = self.instance.slot.available_counsellors
        else
            options = User.objects.none()
        self.fields['counsellor'].queryset = options

对于Django管理员,这样的操作应该有效:

class ChatSessionAdmin(admin.ModelAdmin):
    def render_change_form(self, request, context, *args, **kwargs):
        if kwargs['obj'].slot:
            options = kwargs['obj'].slot.available_counsellors
        else:
            options = User.objects.none()
        context['adminform'].form.fields['counsellor'].queryset = options
        return super(ChatSessionAdmin, self).render_change_form(request, context, args, kwargs)