Python UpdateView(基于类的视图)中的成功消息需要PK或ID

Python UpdateView(基于类的视图)中的成功消息需要PK或ID,python,django,django-class-based-views,Python,Django,Django Class Based Views,我想在UpdateView中发送一条成功消息,其中包含一个链接,允许用户改变对更新的看法。这意味着我需要主键 我无法确定如何在UpdateView中检索主键。其他一切都可以工作,所以你会在我的代码中看到,我有理由将主键硬编码为434 我是所有编程的新手,所以我相信这里有一些愚蠢的东西。我试着一次减少一点我愚蠢的东西。因此,我主要想关注如何检索PK(或ID)。谢谢 网址: # CLASS BASED VIEWS # path('event/list', EventListView.as_view(

我想在UpdateView中发送一条成功消息,其中包含一个链接,允许用户改变对更新的看法。这意味着我需要主键

我无法确定如何在UpdateView中检索主键。其他一切都可以工作,所以你会在我的代码中看到,我有理由将主键硬编码为434

我是所有编程的新手,所以我相信这里有一些愚蠢的东西。我试着一次减少一点我愚蠢的东西。因此,我主要想关注如何检索PK(或ID)。谢谢

网址:

# CLASS BASED VIEWS #
path('event/list', EventListView.as_view(), name='list'),
path('event/detail/<int:pk>', EventDetailView.as_view(), name='detail'),
path('event/create', EventCreateView.as_view(), name='create'),
path('event/update/<int:pk>', EventUpdateView.as_view(), name='update'),
class EventUpdateView(SuccessMessageMixin,UpdateView):

    template_name = 'update.html'
    form_class = EventForm
    success_url = '../list'
    queryset = Event.objects.all()

    def get_object(self, queryset=None):  # here we override the get_object method in UpdateView, don't need queryset
        #obj = Event.objects.get(id=self.kwargs['pk'])
        pk_=self.kwargs.get("pk")
        print("The pk is", pk_)
        return get_object_or_404(Event,pk=pk_)

    def form_valid(self, form):
        return super().form_valid(form)

    message_part_1 = "Record has been updated <a href='unupdate?recordtobeunupdated="
    message_part_2 =  '434'
    message_part_3 = "'>Undo</a>"
    undo_message = message_part_1  + message_part_2 + message_part_3
    success_message = (mark_safe(undo_message))
from django.db import models
from django.urls import reverse

class Event(models.Model):  # This is our database table
    company = models.CharField(default='UL',   max_length=20)
    engine = models.CharField(blank=True, max_length=15)
    date = models.DateTimeField(default=datetime.now, blank=True, null=True)  # default the date to today
    category = models.CharField(max_length=20, choices=CATEGORY_CHOICES, default='Weights')
    description = models.TextField(blank=True, null=True)
    reason = models.TextField(blank=True, null=True)
    assess_date = models.DateTimeField(null=True, blank=True)
    outcome = models.CharField(blank=True, max_length=200)
    # the default is True, it can't be blank
    visible = models.BooleanField(default=True, blank=False)


    def get_absolute_url(self):
        return reverse("SiteEventsAPP: SiteEventsAPP-detail", kwargs={"pk": self.pk})

    # See below __str__(self) is a special method
    # It does a cool thing
    # Whenever Python asks for a string representation of my Event object, this method returns a human-readable version
    # If there is no string method, then Python returns the object type
    # This class method is really only needed for the admin page

    def __str__(self):
        return self.engine  # I have to have a field here. Whatever field I pick will be the field shown in admin

以下是用户看到的结果:

您可以使用django内置消息:

# CLASS BASED VIEWS #
path('event/list', EventListView.as_view(), name='list'),
path('event/detail/<int:pk>', EventDetailView.as_view(), name='detail'),
path('event/create', EventCreateView.as_view(), name='create'),
path('event/update/<int:pk>', EventUpdateView.as_view(), name='update'),
class EventUpdateView(SuccessMessageMixin,UpdateView):

    template_name = 'update.html'
    form_class = EventForm
    success_url = '../list'
    queryset = Event.objects.all()

    def get_object(self, queryset=None):  # here we override the get_object method in UpdateView, don't need queryset
        #obj = Event.objects.get(id=self.kwargs['pk'])
        pk_=self.kwargs.get("pk")
        print("The pk is", pk_)
        return get_object_or_404(Event,pk=pk_)

    def form_valid(self, form):
        return super().form_valid(form)

    message_part_1 = "Record has been updated <a href='unupdate?recordtobeunupdated="
    message_part_2 =  '434'
    message_part_3 = "'>Undo</a>"
    undo_message = message_part_1  + message_part_2 + message_part_3
    success_message = (mark_safe(undo_message))
from django.db import models
from django.urls import reverse

class Event(models.Model):  # This is our database table
    company = models.CharField(default='UL',   max_length=20)
    engine = models.CharField(blank=True, max_length=15)
    date = models.DateTimeField(default=datetime.now, blank=True, null=True)  # default the date to today
    category = models.CharField(max_length=20, choices=CATEGORY_CHOICES, default='Weights')
    description = models.TextField(blank=True, null=True)
    reason = models.TextField(blank=True, null=True)
    assess_date = models.DateTimeField(null=True, blank=True)
    outcome = models.CharField(blank=True, max_length=200)
    # the default is True, it can't be blank
    visible = models.BooleanField(default=True, blank=False)


    def get_absolute_url(self):
        return reverse("SiteEventsAPP: SiteEventsAPP-detail", kwargs={"pk": self.pk})

    # See below __str__(self) is a special method
    # It does a cool thing
    # Whenever Python asks for a string representation of my Event object, this method returns a human-readable version
    # If there is no string method, then Python returns the object type
    # This class method is really only needed for the admin page

    def __str__(self):
        return self.engine  # I have to have a field here. Whatever field I pick will be the field shown in admin
def form_valid(self, form):
        messages.add_message(
            self.request, 
            messages.SUCCESS, 
            """
            Record has been updated <a href="unupdate?recordtobeunupdated={}">Undo</a>""".format(
                kwargs={'pk': self.kwargs['pk']}
             """"
        )

        return super(UserUpdate, self).form_valid(form)
def form_有效(self,form):
messages.add_消息(
自我要求,
信息,成功,
"""
记录已更新为“”。格式为“”(
kwargs={'pk':self.kwargs['pk']}
""""
)
返回super(UserUpdate,self).form\u有效(form)
使用kwargs={'pk':self.kwargs['pk']}您将获得id

之后,您可以在模板中捕获消息:

{% if messages %}
    {% for msg in messages %}
      <div class="alert
      alert-{% if msg.level_tag == 'debug' %}rose{% endif %}
      {% if msg.level_tag == 'info' %}info{% endif %}
      {% if msg.level_tag == 'success' %}success{% endif %}
      {% if msg.level_tag == 'warning' %}warning{% endif %}
      {% if msg.level_tag == 'error' %}danger{% endif %} alert-with-icon" data-notify="container">
        <i class="material-icons" data-notify="icon">
          {% if msg.level_tag == 'debug' %}code{% endif %}
          {% if msg.level_tag == 'info' %}info{% endif %}
          {% if msg.level_tag == 'success' %}done_all{% endif %}
          {% if msg.level_tag == 'warning' %}warning{% endif %}
          {% if msg.level_tag == 'error' %}error{% endif %}
        </i>
        <button type="button" class="close" data-dismiss="alert" aria-label="Close">
          <i class="material-icons">close</i>
        </button>
        <span data-notify="message">
          {% autoescape off %}
            {{ msg.message }}
          {% endautoescape %}
        </span>
      </div>
    {% endfor %}
  {% endif %}
{%if消息%}
{消息%中的msg为%0}
{%if msg.level_标记=='debug'}代码{%endif%}
{%if msg.level_标记=='info%}info{%endif%}
{%if msg.level_标记=='success%}done_all{%endif%}
{%if msg.level_标记=='警告'%}警告{%endif%}
{%if msg.level_标记=='错误'%}错误{%endif%}
关闭
{%autoescape off%}
{{msg.message}}
{%endautoescape%}
{%endfor%}
{%endif%}
上面的代码捕获每条消息(假设您使用的是常规布局),并使用引导将消息呈现为通知


更多信息

如果您检查成功消息的代码,您将看到:

    class SuccessMessageMixin:
    """
    Add a success message on successful form submission.
    """
    success_message = ''

    def form_valid(self, form):
        response = super().form_valid(form)
        success_message = self.get_success_message(form.cleaned_data)
        if success_message:
            messages.success(self.request, success_message)
        return response

    def get_success_message(self, cleaned_data):
        return self.success_message % cleaned_data
正如您在这里看到的,返回成功消息的函数是
get\u success\u message
,因此您只需重写该函数

您的代码应该是:

class EventUpdateView(SuccessMessageMixin,UpdateView):

    template_name = 'update.html'
    form_class = EventForm
    success_url = '../list'
    queryset = Event.objects.all()    

    def form_valid(self, form):
        return super().form_valid(form)

    def get_success_message(self, cleaned_data):
        message = "Record has been updated <a href='unupdate?recordtobeunupdated="
        message += str(self.kwargs.get("pk"))
        message += "'>Undo</a>"
        return (mark_safe(message))
class EventUpdateView(成功消息更新视图):
模板名称='update.html'
form\u class=EventForm
成功\u url=“../list”
queryset=Event.objects.all()
def表单_有效(自身、表单):
返回super().form_有效(form)
def get_success_消息(自身、已清理的_数据):
message=“记录已更新”
返回(标记安全(消息))
让我给你一个建议,永远不要将python库/框架视为黑盒实体,只需输入它们并探索它们是如何工作的,这将使您的编程生活更加轻松


祝你好运,继续努力吧!

你打算如何处理这个成功消息?它不是任何内置的基于类的视图的标准属性。Daniel,我在上面添加了一个片段来向你展示“撤消”是什么需要PK。但是如果你有更好的想法,我很感兴趣。是的,但是你打算如何将该消息从类传递到模板?(此外,它不会影响您的问题,但请注意,您的
get\u对象
方法是不必要的-它只执行默认实现已经执行的操作。只有当您想执行异常操作时,才需要重写
get\u对象
。您应该删除您的版本。)好的,可以。这是一次试图检索PK的尝试,但失败了。谢谢,Hagyn。这成功了,我理解。正如Daniel指出的,我删除了不必要的get_对象,我将您的最后一行代码编辑为message而不是undo_message。很高兴它成功了!我想您也可以删除form_valid方法,您只是在调用super。好的,我删除了有效的表格。再次感谢。