How to define django foreign key limit_choices_to constraint which has reference to it's own model?
-
14-06-2021 - |
Domanda
Here are the models. I need to avoid the reference of Filter objects in the FilterValue model which are being already referenced in the FilterValue model.
class Filter(models.Model):
name = models.CharField('Name', max_length=255)
class FilterValue(models.Model):
name = models.CharField('Name', max_length=255)
filter = models.ForeignKey(Filter, limit_choices_to=Q(***?***))
I'm looking for what could be the possible in place of ?.
Soluzione
As I understood from the OP's comment, the idea is to forbid adding duplicate entries.
But there is a more secure way of doing that:
class FilterValue(models.Model):
name = models.CharField('Name', max_length=255)
filter = models.ForeignKey(Filter)
class Meta:
unique_together = (("name", "filter"),)
The original solution will just display a list of Filters in the Admin, of in a Form, but will not actually forbid to add a duplicate programatically.
Altri suggerimenti
You can't do it in that way, but you can do it as part of a form. Specifically, during the __init__
method of a form, you can alter the queryset of a related field.
I wrote about how to do this in the admin at Filtering querysets in django.contrib.admin forms
I did it in another way by making FilterValueAdmin edit-only in admin and adding the same as inline in FilterAdmin model.
class FilterValueInline(admin.StackedInline):
formset = FilterValueInlineFormset
model = FilterValue
max_num = 1
can_delete = False
class FilterAdmin(admin.ModelAdmin):
list_display = ('id', 'name')
inlines = [FilterValueInline]
class FilterValueAdmin(admin.ModelAdmin):
"""Filter value has to be added via the filter table"""
def has_add_permission(self, request):
return False
def has_delete_permission(self, request, obj=None):
return False
actions = None
list_display = ('id', 'name', 'filter')