dimanche 12 février 2017

Recent Questions - Stack Overflow

The Problem

Summarised: How do I populate a pre-rendered Django ChoiceField / ModelChoiceField dynamically when using Angular http service to retrieve data from server.

I am unable to populate a Django ModelChoiceField with returned data from a function. I did have this working with angular templating, however the problem is that I will be unable to validate these fields with form.is_valid() before saving to the database as currently I have hardcoded the <select> fields into my html.

The reason why I have a ModelChoiceField is because I have tried filtering the values of the notification_type and appending them to the notification_type field. Even though the form field was populated successfully with values, I was unable to return data and display within my templates as I have a Angular controller expecting the data.

The Code

html

<div>
    <label>Select department</label>
    <div>
        
    </div>
</div>
<div>
    <label>Select notification type</label>
    <div ng-controller="selectNotificationTypeCtlr">
        <select ng-change="getNotfications()" ng-model="selectedNotificationType">
                <option ng-repeat="i in notificationTypes" value="{[{ i.pk }]}">{[{ i.fields.notification_type }]}</option> <!-- fields.notification_type -->
        </select>
    </div>
</div>

app.js

selectNotification.controller('selectDepartmentCtlr', function($scope, $http) {
$scope.getNotificationType = function() {
    var id = $scope.selectedDepartment;
    var notificationTypes = [];
    $http({
        method : "GET",
        url : id
     }).then(function success(response) {
        $scope.notificationTypes = response.data;
     }, function error(response) {
        var errorMessage = "Oops it looks like something went wrong. Please try again.";
     });
   };
});

As you can see I understand the process, its just integrating it with Django forms.

views.py

@login_required(login_url="/login/")
def get_notification_types(request, id):
if request.method == "GET":
    department = Department.objects.get(id=id)
    notification_types = NotificationType.objects.filter(department=department.id)
    return HttpResponse(serializers.serialize('json', notification_types))

forms.py

from django import forms
from notifications.models import Department
from notifications.models import NotificationType


class SelectNotificationForm(forms.Form):
    department = forms.ModelChoiceField(queryset=Department.objects.all(), widget=forms.Select(attrs={'class':'input-element', 'ng-change':'getNotificationType()', 'ng-model':'selectedDepartment'})) #widget=forms.Select(attrs={'class': 'add_class_here'}) # ChoiceField(widget=forms.Select()
    notification_type = forms.ModelChoiceField(queryset=NotificationType.objects.none(), widget=forms.Select(attrs={'class':'input-element'}))
    notification_name = forms.ChoiceField(widget=forms.Select(attrs={'class':'input-element'}))
    notification_contacts = forms.MultipleChoiceField(widget=forms.SelectMultiple(attrs={'class':'input-element'}))
    subject = forms.CharField(widget=forms.Select(attrs={'class':'input-element'}))
    body = forms.CharField(widget=forms.Textarea)

How it's displayed

Here's the site functioning with my current code.

Screenshot of site

The helping hand I need

I would like to use Django to validate my form via the is_valid() function when it is saved, but I also need to populate the second ChoiceField with the JSON data object returned to my Angular Controller. The thing that's really fustrating me is that it works fine with Angular, its just the fact that I need to use the which prevents me from looping through and displaying the returned JSON object from my Angular controller.

html template that would allow me to validate the ChoiceField / ModelChoiceFields

html (Ideally I would like to render the form as per the code below, so I can validate the form.)

<div>
    <label>Select department</label>
    <div>
        
    </div>
</div>
<div>
    <label>Select notification type</label>
    <div ng-controller="selectNotificationTypeCtlr">
        
    </div>
</div>

I am aware of a workaround which would subsequently mean me setting required=False on all of the forms ChoiceFields. However, I feel this may cause issues further down the line.

Any advice or help would be much appreciated.

Solution ("ng-options" directive):

        notification_type = forms.ModelChoiceField(queryset=NotificationType.objects.none(), widget=forms.Select(attrs={'class':'input-element', 'ng-focus':'populateNotificationTypes()', 'ng-change':'x()', 'ng-model':'selectedNotificationType', 'ng-options':'x as x.fields.notification_type for x in notificationTypes', 'ng-model':'selectedNotificationType'}))

The only issue I'm having now is that values within options are displayed as value="object:id" where the id is the id of the notification_type.

Let's block ads! (Why?)



Recent Questions - Stack Overflow

Aucun commentaire:

Enregistrer un commentaire