Django:如何在不刷新页面的情况下更新图像?

Posted

技术标签:

【中文标题】Django:如何在不刷新页面的情况下更新图像?【英文标题】:Django: How to update an image without refreshing the page? 【发布时间】:2021-09-14 09:55:51 【问题描述】:

我在 Djnago 工作,我想在不重新加载或刷新页面的情况下更新图像。我已经使用 Ajax 的 get 方法来接收图像,它也可以工作,但是要查看新图像,我必须刷新页面。此图像由views.py 文件中的bfs_view 方法生成。首先,它接收文本形式的输入,然后根据给定的输入生成新图像。

views.py 文件:


# def product_create_view(request):
def bfs_view(request):
    form = BFSForm(request.POST or None)
    if form.is_valid():
        form.save()
        form = BFSForm()
    try:
        image_url_info = None
        num_states_explored = None
        final_solution = None

        text_file = open("BFS\outputs\maze.txt", "w")
        field_name = 'description'
        input_value = BFS.objects.latest('id')

        field_object = BFS._meta.get_field(field_name)
        field_value = field_object.value_from_object(input_value)


        field_string_value = str(field_value).split("\n")

        text_file.writelines(field_string_value)
        text_file.close()

        m = Maze("BFS\outputs\maze.txt")
        print("Maze:")
        m.print()
        print("Solving...")
        m.solve()
        print("States Explored:", m.num_explored)
        print("Solution:")
        m.print()

        m.output_image("BFS\outputs\maze.png", show_explored=True)
        m.output_image("static/search/bfs/maze.png", show_explored=True)

        image_url_info = "/../../../static/search/bfs/maze.png"
        num_states_explored = m.num_explored
        
        # final_solution = ''.join(m.end_result)
        final_solution = str(''.join(m.end_result))
        print(''.join(m.end_result))
        get_bfs_image_view(request)

        # BFS.objects.latest('id').delete()
    except:
        print("BFS ERROR: Error in the try session of BFS in view.py")

    context = 
        'form': form, 'image_url': image_url_info, 'states_explored': num_states_explored, 
        'solution': final_solution

    return render(request, "BFS/bfs.html", context)


def post_bfs_view(request):
    if request.method == "POST" and request.is_ajax():
        bfs_view(request)
        return JsonResponse("success":True, status=200)
    return JsonResponse("success":False, status=400)


def get_bfs_view(request):
    if request.method == "GET" and request.is_ajax():
        try:
            image_url_info = None
            num_states_explored = None
            final_solution = None

            text_file = open("BFS\outputs\maze.txt", "w")
            field_name = 'description'
            input_value = BFS.objects.latest('id')

            field_object = BFS._meta.get_field(field_name)
            field_value = field_object.value_from_object(input_value)


            field_string_value = str(field_value).split("\n")

            text_file.writelines(field_string_value)
            text_file.close()

            m = Maze("BFS\outputs\maze.txt")
            print("Maze:")
            m.print()
            print("Solving...")
            m.solve()
            print("States Explored:", m.num_explored)
            print("Solution:")
            m.print()

            m.output_image("static/search/bfs/maze.png", show_explored=True)
            image_url_info = "/../../../static/search/bfs/maze.png"
            
            # final_solution = ''.join(m.end_result)
            final_solution = str(''.join(m.end_result))
            print(''.join(m.end_result))
            # bfs_view(request)

            # BFS.objects.latest('id').delete()
            bfs_view(request)
        except:
            print("BFS ERROR: Error in the try session of BFS in view.py")
    return HttpResponse(final_solution)


def get_bfs_image_view(request):
    if request.method == "GET" and request.is_ajax():
        try:
            image_url_info = "/../../../static/search/bfs/maze.png"

        except:
            print("BFS ERROR: Error in the try session of BFS in view.py")
    return HttpResponse(image_url_info)

我用来更新图像的视图函数:

def get_bfs_image_view(request):
    if request.method == "GET" and request.is_ajax():
        try:
            image_url_info = "/../../../static/search/bfs/maze.png"

        except:
            print("BFS ERROR: Error in the try session of BFS in view.py")
    return HttpResponse(image_url_info)

bfs.html 主文件:

<form id = "contactForm" method='POST' >% csrf_token %
    form.as_p 
   <input type='submit' value='Search' class="submit-btn poppins"/>
</form>

  <pre><span id="myText"></span></pre>
  <div id="myimage"></div>

我使用的ajax:

<script>
$(document).ready(function()
    $("#contactForm").submit(function(e)
        // prevent from normal form behaviour

        e.preventDefault();
        // serialize the form data

        var serializedData = $(this).serialize();
        $.ajax(
            type : 'POST',
            url :  "% url 'BFS:contact_submit' %",
            data : serializedData,

            success : function(response)
                //reset the form after successful submit
                $("#contactForm")[0].reset();

                // This will then call for the get request to update the id "myText"
                live_update();
                live_image_update();
            ,

            error : function(response)
               console.log(response)
            
       );
   );

   function live_update()
       $.ajax(
           url: "% url 'BFS:get_user_info' %",
           type: 'get', // This is the default though, you don't actually need to always mention it

           success: function(data) 
               var number = data;
               document.getElementById("myText").innerHTML = number;
               $("#myText").hide();
                $("#myText").html(data);
                $("#myText").fadeIn(1000);
           ,

           error: function() 
               alert('Got an error dude');
           
      );
   

   function live_image_update()
       $.ajax(
           url: "% url 'BFS:get_bfs_image_info' %",
           type: 'get', // This is the default though, you don't actually need to always mention it

           success: function(data) 
            $('#myimage').html('<img src="/../../../static/search/bfs/maze.png" />');
           ,

           error: function() 
               alert('Got an error dude');
           
      );
   
);

</script>

我用来更新图片的ajax:

function live_image_update()
       $.ajax(
           url: "% url 'BFS:get_bfs_image_info' %",
           type: 'get', // This is the default though, you don't actually need to always mention it

           success: function(data) 
            $('#myimage').html('<img src="/../../../static/search/bfs/maze.png" />');
           ,

           error: function() 
               alert('Got an error dude');
           
      );
   
);

urls.py 浏览量:

app_name = 'BFS'

urlpatterns = [
    path('bfs/', bfs_view),
    path('ajax/contact', post_bfs_view, name ='contact_submit'),
    path('ajax/get_user_info', get_bfs_view, name = 'get_user_info'),
    path('ajax/get_bfs_image_info', get_bfs_image_view, name = 'get_bfs_image_info'),
]

models.py 文件:

class BFS(models.Model):
    description = models.TextField(blank=True, null=True)

    def __str__(self):
        return self.description

forms.py 文件:

from django import forms
from .models import BFS

class BFSForm(forms.ModelForm):
    description = forms.CharField(
                        required=False, 
                        label=False,
                        widget=forms.Textarea(
                                attrs=
                                    'id': 'TA1',
                                    'rows': '10vh',
                                    'cols': '8vw',
                                    'placeholder': 'Enter Your Map Here',
                                    'class': 'textfield-style',
                                    'style': 'max-width: 100%; max-height: 100%;outline: none; border: none; background-color: white; width: 100%; padding: 12px 20px; margin: 8px 0; box-sizing: border-box; font-size: 20px; spellcheck="false";',
                                
                            )
                        )
    
    class Meta:
        model = BFS
        fields = [
            'description'
        ]

    def __init__(self, *args, **kwargs):
        super(BFSForm, self).__init__(*args, **kwargs)
        for field in self.fields:
            self.fields[field].widget.attrs.update(
            'class': 'form-control')

【问题讨论】:

您可能对 htmx 感兴趣。 htmx.org 参见 dev.to/nicholas_moen/… 示例 【参考方案1】:

看起来您每次都将图像 URL 设置为相同的值,因此由于客户端缓存,您看不到替换的图像。

解决此问题的最简单方法是为每个生成的图像使用不同的文件名。另一个简单的方法可能是调整 URL 使其成为不同的请求,因此如果您更改 live_image_update 成功回调以附加时间戳查询字符串,那么您将触发新请求并查看新图像。

function live_image_update()
   $.ajax(
       url: "% url 'BFS:get_bfs_image_info' %",
       type: 'get', // This is the default though, you don't actually need to always mention it

       success: function(data) 
        $('#myimage').html('<img src="/../../../static/search/bfs/maze.png?' + 
          Date.now() + '/>');
       ,

       error: function() 
           alert('Got an error dude');
       
  );

【讨论】:

以上是关于Django:如何在不刷新页面的情况下更新图像?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在不刷新整个页面的情况下刷新包含的 Django 模板?

如何使用 Django、Ajax、jQuery 在不刷新页面的情况下提交表单?

如何在不刷新页面的情况下使用 django-crispy-forms 实现引导模式表单

如何在不刷新页面的情况下更新角度数据?

如何在不刷新页面的情况下定期更新数据?

如何在不刷新 php 页面的情况下更新/移动我的 canvasjs 图表