简体   繁体   中英

Django, admin panel, dependence of the values of one ForeignKey field available for selection on the value selected in another ForeignKey field

I have models:

models.py

class CommentCollection(models.Model):
      name = models.CharField(max_length=50)


class Comment(models.Model):
      comments_collection = models.ForeignKey(CommentCollection, related_name='comments', on_delete=models.CASCADE)
      reply_to = models.ForeignKey('self', related_name='replies', null=True, blank=True, on_delete=models.CASCADE)
      text = models.TextField()
      user = models.ForeignKey(User, related_name='user_comments', on_delete=models.CASCADE)
      created = models.DateTimeField(auto_now_add=True)
      is_public = models.BooleanField(default=False, verbose_name='Published')

<admin.py>

@admin.register(CommentCollection)
class CommentCollectionAdmin(admin.ModelAdmin):
      list_display = ['id', 'name']

How to make it so that: When adding a new comment via the admin panel, after filling in the "comments_collection" field (selection from the CommentCollection model), only those comments that belong to the same collection of comments are displayed in the reply_to field for selection.

@admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
      list_display = ('comments_collection', 'user', 'created', 'is_public')

add below code to your CommentAdmin . when you do modification, there is no need to JS, but for adding a new option, you need to pass data from FE to BE. I'm not sure if add part will work, but you can get an idea...

def render_change_form(self, request, context, add, change, form_url, obj):
    if add:
        collection_id = (
            request.GET.get("comment_collection")
            if request.GET.get("comment_collection")
            else -1
        )
    if change:
        collection_id = obj.comments_collection.id
    reply_to_qs = context["adminform"].form.fields["reply_to"].queryset

    context["adminform"].form.fields["reply_to"].queryset = reply_to_qs.filter(
        comments_collection_id=collection_id
    )
    return super().render_change_form(request, context, add, change, form_url, obj)

create a file at this location for more detail refer to django doc.

project/app_name/templates/admin/app_name/change_form.html

{% extends "admin/change_form.html" %}
{% load admin_urls static admin_modify %}  
{% block footer %}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script>
    commentSelection = document.getElementById("id_comments_collection")
    commentSelection.onchange = function() {
            $.ajax({
                type: 'GET',
                url: "{% url 'admin:app_name_comment_add' %}",
                data: {"comment_collection": commentSelection.value},
                success: function (response) {
                    console.log(commentSelection.value);
                },
                error: function (response) {
                    console.log(response)
                }
            })
    }
</script>
{% endblock %}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM