0

I'm fairly new to Django, but wondering how to get one seemingly obvious thing to work in my model definitions.

For a model "Product" I want to be able to add any number of links, so I made a more or less generic "Link" model with a display name field and a URL field. In Product I add this as ManyToManyField with the respective Link model.

This works like intended in the admin view in that I can add any number of links and do so inline. However, I only want the admin view to list existing links of this product, let the user delete them, and let the user add new ones. What I do not want is for the inline link field to display all other product’s links.

Am I confused with the Field Type or overall approach, or how can I get this to work? I was wondering if the through options is the way to do this, or if this is merely something you should do in the admin forms and not on model level?

Edit: Code sample added below

Edit: Code sample updated with formfield_for_manytomany

In models.py:

class Product(models.Model):
    name = models.CharField(max_length=256)
    links = models.ManyToManyField('Link', related_name='links', default=None, blank=True, null=True)

class Link(models.Model):
    name = models.CharField(max_length=256)
    url = models.URLField(max_length=256)

In admin.py:

class LinksInline(admin.StackedInline):
    model = Link

class ProductAdmin(admin.ModelAdmin):
    inlines = [LinksInline]

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        kwargs["queryset"] = Link.objects.filter(font_id=self.object_id)
        return super().formfield_for_manytomany(db_field, request, **kwargs)

admin.site.register(Link)
admin.site.register(Product)
kontur
  • 4,934
  • 2
  • 36
  • 62
  • Do you mean that you want to filter the inline manytomanyfield's queryset by the product that you are adding/editing? – Sachin Nov 29 '18 at 08:38
  • @SachinKukreja If that is the way to do this most commonly in Django, then yes. My Link model is just a generic piece of data I want repeated, maybe even in several other models. I am interested in making those fields have same structure, but I am not interested in actually cross-populating the objects across models that use the Link model. – kontur Nov 29 '18 at 08:46
  • Please post some relevant code showing what you have already done. – Sachin Nov 29 '18 at 08:51
  • @SachinKukreja I've update the question with the essential parts. – kontur Nov 29 '18 at 08:57
  • I've found [this](https://stackoverflow.com/questions/1226760/filter-manytomany-box-in-django-admin) question which seems to do something like I am looking for, but as per my edited code the `formfield_for_manytomany` function does not seem to be having any effect. I tried placing log statements in that method, but they never get logged. – kontur Nov 29 '18 at 09:41
  • Take a look at [this](https://stackoverflow.com/a/5216214/5312750) – Sachin Nov 29 '18 at 10:04
  • Not sure what I am doing wrong but somehow the my code inside `formfield_for_manytomany` never seems to get run. I've added debug traces before, and in the method, and the ones in the method never show. I suspect otherwise this would be the right direction. – kontur Nov 30 '18 at 07:50

1 Answers1

0

The mistake was very obvious, the filtering in the ProductAdmin never came into effect, because it was not registered:

admin.site.register(Link)
admin.site.register(Product, ProductAdmin)

Edit: Now that I've further attempted to get this working I notice that the entire question is unnecessary based on the fact that out of the box the inline behavior is just what I wanted — only I thought it did not work due to the missing ProductAdmin register. Simply registering the Inline and defining the the Link model with a ForeignKey to the Product will take care of this. Following the link in the comments, I did get the non-inline select box to filter as described, using the stored object to filter the manytomany result against — alas, it is not needed.

kontur
  • 4,934
  • 2
  • 36
  • 62