Wednesday, 1 September 2021

Prevent django formset submission if empty

I have a form that I only want users to be able to submit if a field in a formset is filled. This is a dynamic formset in which users can add and remove rows, I want it so that at least one row needs to have an entry in it. However it seems that the formset is able to be submitted even if not valid.

For example if the user does not put an entry for 'age' a popup will request that they enter something. This does not occur for 'diagnosis'

models.py

class Patient(TimeStampedModel):
    patient_id = models.UUIDField(primary_key=True, unique=True, default=uuid.uuid4, editable=False)
    
    age = models.IntegerField("Age")

    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        null=True,
        on_delete=models.SET_NULL)

    
class Diagnosis(TimeStampedModel):
    
    DIAG_CHOICES = [
        (‘heart’, (
                (‘mi’, ‘heart attack’),
                (‘chf’, ‘heart failure’),
            )
        ),
        (‘kidney’, (
                (‘arf’, ‘acute renal failure’),
                (‘crf’, ‘chronic renal failure’),
            )
        ),
        ]
    
    diag_name = models.CharField(
        "diag", max_length=200,
        choices=DIAG_CHOICES, blank=False)

    patient = models.ForeignKey(Patient, on_delete=models.CASCADE)

forms.py

class PatientForm(ModelForm):

    class Meta:
        model = Patient
        fields = ['age']


DiagnosisFormSet = inlineformset_factory(
    Patient, Diagnosis, fields=("diag_name", ), extra=0, min_num=1, validate_min=True)

views.py


class PatientAddView(LoginRequiredMixin,TemplateView):
    model = Patient
    template_name = "../templates/patient/add.html"

    def get(self, *args, **kwargs):
        patient_form = PatientForm
        diagnosis_formset = DiagnosisFormSet(queryset=Diagnosis.objects.none())

        return self.render_to_response({'diagnosis_formset': diagnosis_formset,
                                        'patient_form': patient_form
                                })

    def post(self, *args, **kwargs):
        form = PatientForm(data=self.request.POST)
        diagnosis_formset = DiagnosisFormSet(data=self.request.POST)

        if form.is_valid(): 
            patient_instance = form.save()
            patient_instance.user = self.request.user
            patient_instance.save()

            if diagnosis_formset.is_valid():
                diag_name = diagnosis_formset.save(commit=False)
                for diag in diag_name:
                    diag.patient = patient_instance
                    diag.save()
          

        return redirect(reverse(
                        'patient:treatment_detail',
                        kwargs={"patient_id": patient_instance.patient_id}))



from Prevent django formset submission if empty

How to reuse route on query params change, but not on path params change in Angular?

Say I have 2 routes '/users' and /users/:id. First one renders UserListComponent and second UserViewComponent.

I want to re-render component when navigating from /users/1 to /users/2. And of course if I navigate from /users to /users/1 and vice versa.

But I DON'T want to re-render component if I navigate from /users/1?tab=contacts to /users/1?tab=accounts.

Is there a way to configure router like this for entire application?

--

Update:

I'm importing RouterModule in AppRoutingModule like this:

RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })

I'm using Angular 12



from How to reuse route on query params change, but not on path params change in Angular?

add relevant information tooltip echarts4r boxplot outliers

I am trying to add some relevant hover information to the tooltip of a echarts4r plot. I want to make an boxplot that shows the user the name (or some other information) of the outliers. This is somewhat related to Add extra variables to tooltip pie chart echarts4r and Add extra variables to tooltip pie chart echarts4r, but those solutions do not work as bind = does not work for e_boxplot.

This is what I have so far

library(echarts4r)

df <- data.frame(
  my_name = letters[1:11],
  x = c(1:10, 25),
  y = c(1:10, -6)
) 

df |>
  e_charts() |>
  e_boxplot(y, outliers = TRUE) |>
  e_boxplot(x, outliers = TRUE) |>
  e_tooltip(formatter = htmlwidgets::JS("
                                        function(params)
                                        {
                                            return `<strong>${params.name}</strong>
                                                    <br/>val: ${params.value[1]}
                                                    <br/>name: ${params.my_name}`
                                        }  "))




from add relevant information tooltip echarts4r boxplot outliers