Django admin sending a message based on inline formset












0














I'm writing a reservation program using the Django admin. The program will warn the user (via Django messages) when the total nights for all room changes is greater than the total nights for the reservation. So if a reservation is for 7 nights and the user enters the guest into room "A" for 4 nights and room "B" for 4 nights (totaling 8 nights) the user will see a warning. The reason for a warning and not a simple form error is that a group can have multiple rooms per night, which would make it possible for the above to occur.



The code works (below is the relevant pieces).



warn_if_rc_nights_gt_reservation_nights(), which houses the logic to warn the user, operates on the form instance (when the form is only being rendered) or the raw request.POST variables (when the form is being saved/POSTed) in order to tally up the total nights for room changes and reservations.



I'm OK with using the form instance to tally the total nights, but I have a problem with the raw POST variables, since it's more error-prone (POST variables are not clean() yet) and un-Django-like. I'd rather use a built-in class method or function to accomplish this.



I've tried to accomplish this:





  • Within the form.clean() method. This only works when the form is saved, so the user doesn't see the warning when simply navigating to the page.


  • Using various Django signals. Couldn't find a signal that had all the objects I needed to perform the action and that would fire under all circumstances.


reservations.models



class Room(models.Model):
room_number = models.CharField(max_length=16)

class Reservation(models.Model):
# Guest is in guest.models
guest = models.ForeignKey(Guest, on_delete=models.CASCADE)
check_in_date = models.DateField()
check_out_date = models.DateField()

class RoomChange(models.Model):
reservation = models.ForeignKey(Reservation on_delete=models.CASCADE)
room = models.ForeignKey(Room on_delete=models.CASCADE)
day_in = models.DateField()
day_out = models.DateField()


reservations.admin



@admin.register(Reservation)
class ReservationAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
# Uses a form factory to capture the request object.
self.form = _reservation_form_factory(request)
return super().get_form(request, obj, **kwargs)

@admin.register(Room)
class RoomAdmin(admin.ModelAdmin):
pass

@admin.register(RoomChange)
class RoomChangeAdmin(admin.ModelAdmin):
pass


reservations.forms



def _reservation_form_factory(request):
class ReservationAdminForm(forms.ModelForm):
class Meta:
exclude =
model = Reservation

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Warn the user if total room change nights > reservation total nights
warn_if_rc_nights_gt_reservation_nights(request.POST, self.instance)
return ReservationAdminForm


So ultimately I'm asking for a simpler, less error-prone way to accomplish this task.










share|improve this question



























    0














    I'm writing a reservation program using the Django admin. The program will warn the user (via Django messages) when the total nights for all room changes is greater than the total nights for the reservation. So if a reservation is for 7 nights and the user enters the guest into room "A" for 4 nights and room "B" for 4 nights (totaling 8 nights) the user will see a warning. The reason for a warning and not a simple form error is that a group can have multiple rooms per night, which would make it possible for the above to occur.



    The code works (below is the relevant pieces).



    warn_if_rc_nights_gt_reservation_nights(), which houses the logic to warn the user, operates on the form instance (when the form is only being rendered) or the raw request.POST variables (when the form is being saved/POSTed) in order to tally up the total nights for room changes and reservations.



    I'm OK with using the form instance to tally the total nights, but I have a problem with the raw POST variables, since it's more error-prone (POST variables are not clean() yet) and un-Django-like. I'd rather use a built-in class method or function to accomplish this.



    I've tried to accomplish this:





    • Within the form.clean() method. This only works when the form is saved, so the user doesn't see the warning when simply navigating to the page.


    • Using various Django signals. Couldn't find a signal that had all the objects I needed to perform the action and that would fire under all circumstances.


    reservations.models



    class Room(models.Model):
    room_number = models.CharField(max_length=16)

    class Reservation(models.Model):
    # Guest is in guest.models
    guest = models.ForeignKey(Guest, on_delete=models.CASCADE)
    check_in_date = models.DateField()
    check_out_date = models.DateField()

    class RoomChange(models.Model):
    reservation = models.ForeignKey(Reservation on_delete=models.CASCADE)
    room = models.ForeignKey(Room on_delete=models.CASCADE)
    day_in = models.DateField()
    day_out = models.DateField()


    reservations.admin



    @admin.register(Reservation)
    class ReservationAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
    # Uses a form factory to capture the request object.
    self.form = _reservation_form_factory(request)
    return super().get_form(request, obj, **kwargs)

    @admin.register(Room)
    class RoomAdmin(admin.ModelAdmin):
    pass

    @admin.register(RoomChange)
    class RoomChangeAdmin(admin.ModelAdmin):
    pass


    reservations.forms



    def _reservation_form_factory(request):
    class ReservationAdminForm(forms.ModelForm):
    class Meta:
    exclude =
    model = Reservation

    def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    # Warn the user if total room change nights > reservation total nights
    warn_if_rc_nights_gt_reservation_nights(request.POST, self.instance)
    return ReservationAdminForm


    So ultimately I'm asking for a simpler, less error-prone way to accomplish this task.










    share|improve this question

























      0












      0








      0







      I'm writing a reservation program using the Django admin. The program will warn the user (via Django messages) when the total nights for all room changes is greater than the total nights for the reservation. So if a reservation is for 7 nights and the user enters the guest into room "A" for 4 nights and room "B" for 4 nights (totaling 8 nights) the user will see a warning. The reason for a warning and not a simple form error is that a group can have multiple rooms per night, which would make it possible for the above to occur.



      The code works (below is the relevant pieces).



      warn_if_rc_nights_gt_reservation_nights(), which houses the logic to warn the user, operates on the form instance (when the form is only being rendered) or the raw request.POST variables (when the form is being saved/POSTed) in order to tally up the total nights for room changes and reservations.



      I'm OK with using the form instance to tally the total nights, but I have a problem with the raw POST variables, since it's more error-prone (POST variables are not clean() yet) and un-Django-like. I'd rather use a built-in class method or function to accomplish this.



      I've tried to accomplish this:





      • Within the form.clean() method. This only works when the form is saved, so the user doesn't see the warning when simply navigating to the page.


      • Using various Django signals. Couldn't find a signal that had all the objects I needed to perform the action and that would fire under all circumstances.


      reservations.models



      class Room(models.Model):
      room_number = models.CharField(max_length=16)

      class Reservation(models.Model):
      # Guest is in guest.models
      guest = models.ForeignKey(Guest, on_delete=models.CASCADE)
      check_in_date = models.DateField()
      check_out_date = models.DateField()

      class RoomChange(models.Model):
      reservation = models.ForeignKey(Reservation on_delete=models.CASCADE)
      room = models.ForeignKey(Room on_delete=models.CASCADE)
      day_in = models.DateField()
      day_out = models.DateField()


      reservations.admin



      @admin.register(Reservation)
      class ReservationAdmin(admin.ModelAdmin):
      def get_form(self, request, obj=None, **kwargs):
      # Uses a form factory to capture the request object.
      self.form = _reservation_form_factory(request)
      return super().get_form(request, obj, **kwargs)

      @admin.register(Room)
      class RoomAdmin(admin.ModelAdmin):
      pass

      @admin.register(RoomChange)
      class RoomChangeAdmin(admin.ModelAdmin):
      pass


      reservations.forms



      def _reservation_form_factory(request):
      class ReservationAdminForm(forms.ModelForm):
      class Meta:
      exclude =
      model = Reservation

      def __init__(self, *args, **kwargs):
      super().__init__(*args, **kwargs)
      # Warn the user if total room change nights > reservation total nights
      warn_if_rc_nights_gt_reservation_nights(request.POST, self.instance)
      return ReservationAdminForm


      So ultimately I'm asking for a simpler, less error-prone way to accomplish this task.










      share|improve this question













      I'm writing a reservation program using the Django admin. The program will warn the user (via Django messages) when the total nights for all room changes is greater than the total nights for the reservation. So if a reservation is for 7 nights and the user enters the guest into room "A" for 4 nights and room "B" for 4 nights (totaling 8 nights) the user will see a warning. The reason for a warning and not a simple form error is that a group can have multiple rooms per night, which would make it possible for the above to occur.



      The code works (below is the relevant pieces).



      warn_if_rc_nights_gt_reservation_nights(), which houses the logic to warn the user, operates on the form instance (when the form is only being rendered) or the raw request.POST variables (when the form is being saved/POSTed) in order to tally up the total nights for room changes and reservations.



      I'm OK with using the form instance to tally the total nights, but I have a problem with the raw POST variables, since it's more error-prone (POST variables are not clean() yet) and un-Django-like. I'd rather use a built-in class method or function to accomplish this.



      I've tried to accomplish this:





      • Within the form.clean() method. This only works when the form is saved, so the user doesn't see the warning when simply navigating to the page.


      • Using various Django signals. Couldn't find a signal that had all the objects I needed to perform the action and that would fire under all circumstances.


      reservations.models



      class Room(models.Model):
      room_number = models.CharField(max_length=16)

      class Reservation(models.Model):
      # Guest is in guest.models
      guest = models.ForeignKey(Guest, on_delete=models.CASCADE)
      check_in_date = models.DateField()
      check_out_date = models.DateField()

      class RoomChange(models.Model):
      reservation = models.ForeignKey(Reservation on_delete=models.CASCADE)
      room = models.ForeignKey(Room on_delete=models.CASCADE)
      day_in = models.DateField()
      day_out = models.DateField()


      reservations.admin



      @admin.register(Reservation)
      class ReservationAdmin(admin.ModelAdmin):
      def get_form(self, request, obj=None, **kwargs):
      # Uses a form factory to capture the request object.
      self.form = _reservation_form_factory(request)
      return super().get_form(request, obj, **kwargs)

      @admin.register(Room)
      class RoomAdmin(admin.ModelAdmin):
      pass

      @admin.register(RoomChange)
      class RoomChangeAdmin(admin.ModelAdmin):
      pass


      reservations.forms



      def _reservation_form_factory(request):
      class ReservationAdminForm(forms.ModelForm):
      class Meta:
      exclude =
      model = Reservation

      def __init__(self, *args, **kwargs):
      super().__init__(*args, **kwargs)
      # Warn the user if total room change nights > reservation total nights
      warn_if_rc_nights_gt_reservation_nights(request.POST, self.instance)
      return ReservationAdminForm


      So ultimately I'm asking for a simpler, less error-prone way to accomplish this task.







      python django django-forms django-admin django-messages






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 23 '18 at 13:40









      crazy4linux

      615




      615
























          0






          active

          oldest

          votes











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53447790%2fdjango-admin-sending-a-message-based-on-inline-formset%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53447790%2fdjango-admin-sending-a-message-based-on-inline-formset%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Contact image not getting when fetch all contact list from iPhone by CNContact

          count number of partitions of a set with n elements into k subsets

          A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks