2016-04-04 7 views
0

Django REST Framework meldet einen Fehler, dass ein Wert Null ist, obwohl ich den Wert senden, wenn ich die Daten POST bin.Django wirft Spalte kann nicht Null Fehler sein, wenn POST zu REST Framework

Der Fehler Django berichtet ist:

django.db.utils.IntegrityError: (1048, "Column 'owner_id' cannot be null") 
 
[04/Apr/2016 18:40:58] "POST /api/items/ HTTP/1.1" 500 226814

Der Angular-2-Code, die Beiträge zu Django REST Framework API ist:

let body = JSON.stringify({ url: 'fred', item_type: 'P', owner_id: 2 }); 
 

 
    let headers = new Headers(); 
 
    headers.append('Content-Type', 'application/json'); 
 

 
    this.http.post('http://127.0.0.1:8000/api/items/', 
 
     body, { 
 
     headers: headers 
 
     }) 
 
     .subscribe(
 
     data => { 
 
      alert(JSON.stringify(data)); 
 
     }, 
 
     err => alert('POST ERROR: '+err.json().message), 
 
     () => alert('POST Complete') 
 
    );

Meine Django API Ansicht sieht wie folgt aus:

class ItemViewSet(viewsets.ModelViewSet): 
 
    queryset = Item.objects.all().order_by('-date_added') 
 
    serializer_class = ItemSerializer 
 

 
    """ 
 
     Use the API call query params to determing what to return 
 

 
     API params can be: 
 

 
     ?user=<users_id>&num=<num_of_items_to_return>&from=<user_id_of_items_to_show> 
 
    """ 
 

 
    def get_queryset(self): 
 
     this_user = self.request.query_params.get('user', None) 
 
     restrict_to_items_from_user_id = self.request.query_params.get('from', None) 
 
     quantity = self.request.query_params.get('num', 20) 
 

 
     if restrict_to_items_from_user_id is not None: 
 
      queryset = Item.objects.filter(owner=restrict_to_items_from_user_id, active=True).order_by('-date_added')[0:int(quantity)] 
 
     elif this_user is not None: 
 
      queryset = Item.objects.filter(active=True, credits_left__gt=0).exclude(pk__in=Seen.objects.filter(user_id=this_user).values_list('item_id', flat=True))[0:int(quantity)] 
 
     else: 
 
      queryset = Item.objects.filter(active=True, credits_left__gt=0)[0:int(quantity)] 
 

 
     print("User id param is %s and quantity is %s" % (user_id,quantity)) 
 

 
     return queryset

Das zugehörige Modell ist:

class Item(models.Model): 
 

 
    ITEM_TYPES = (
 
     ('V', 'Vine'), 
 
     ('Y', 'YouTube'), 
 
     ('P', 'Photo'),   # Photo is stored by us on a CDN somewhere 
 
     ('F', 'Flickr'), 
 
     ('I', 'Instagram'), 
 
     ('D', 'DeviantArt'), 
 
     ('5', '500px'), 
 
    ) 
 
    owner   = models.ForeignKey(User, on_delete=models.CASCADE)  # Id of user who owns the item 
 
    title   = models.CharField(max_length=60, default='')   # URL of where item resides (e.g. Vine or YouTube url) 
 
    url    = models.CharField(max_length=250, default='')   # URL of where item resides (e.g. Vine or YouTube url) 
 
    item_type  = models.CharField(max_length=1, choices=ITEM_TYPES) # Type of item (e.g. Vine|YoutTube|Instagram|etc.) 
 
    keywords  = models.ManyToManyField(Keyword, related_name='keywords') 
 
                      # E.g. Art, Travel, Food, etc. 
 
    credits_applied = models.IntegerField(default=10, help_text='Total number of credits applied to this item including any given by VeeU admin') 
 
                      # Records the total number of credits applied to the Item 
 
    credits_left = models.IntegerField(default=10, help_text='The number of credits still remaining to show the item') 
 
                      # Number of credits left (goes down each time item is viewed 
 
    credits_gifted = models.IntegerField(default=0, help_text='The number of credits this item has been gifted by other users') 
 
                      # Number of credits users have gifted to this item 
 
    date_added  = models.DateTimeField(auto_now_add=True)    # When item was added 
 
    liked   = models.IntegerField(default=0)      # Number of times this item has been liked 
 
    disliked  = models.IntegerField(default=0)      # Number of times this item has been disliked 
 
    active   = models.BooleanField(default=True, help_text='If you mark this item inactive please say why in the comment field. E.g. "Inapproriate content"') 
 
                      # True if item is available for showing 
 
    comment   = models.CharField(max_length=100, blank=True)   # Comment to be applied if item is inactive to say why 
 

 
    # Add defs here for model related functions 
 

 
    # This to allow url to be a clickable link 
 
    def item_url(self): 
 
     return u'<a href="%s">%s</a>' % (self.url, self.url) 
 
    item_url.allow_tags = True 
 

 
    def __str__(self): 
 
     return '%s: Title: %s, URL: %s' % (self.owner, self.title, self.url)

Ich kann nicht sehen, was mit falsch ist mein POST-Aufruf oder der Django-Code.

EDIT: Hinzugefügt Serializer Code Hier ist das zugehörige Serializer

class ItemSerializer(serializers.HyperlinkedModelSerializer): 
 
    username = serializers.SerializerMethodField() 
 

 
    def get_username(self, obj): 
 
     value = str(obj.owner) 
 
     return value 
 

 
    def get_keywords(self, obj): 
 
     value = str(obj.keywords) 
 
     return value 
 

 
    class Meta: 
 
     model = Item 
 
     fields = ('url', 'item_type', 'title', 'credits_applied', 'credits_left', 'credits_gifted', 'username', 'liked', 'disliked')

Antwort

0

ich in ein ähnliches Problem lief Angular und Kolben verwendet wird. Dies kann daran liegen, dass Ihre CORS-Header für Ihre Django-App nicht richtig eingestellt sind, sodass Ihre Angular-App nicht zum Backend gelangen kann. In Flask, ich regelte es mit diesem Code:

@app.after_request 
def after_request(response): 
    response.headers.add('Access-Control-Allow-Origin', '*') 
    response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization') 
    response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE') 
    return response 

Ich bin nicht sicher, wie dies in Django zu tun, aber dies kann eine große erste Adresse für Sie sein, da dies wahrscheinlich Ihr Problem ist.

+0

Dank Jaron. Ich laufe gerade auf demselben Ursprung (zum Testen), aber meine CORS Einstellungen sind wie in Ihrem Beispiel. –

+0

Darn Mann zumindest können Sie das von der Liste dann markieren .. Ich bin mir nicht sicher, was könnte schief gehen. Ich werde noch einen Blick darauf werfen und Sie wissen lassen, ob ich etwas sehe. –

+0

Vielleicht hat es etwas damit zu tun, dass der Besitzer ein Fremdschlüssel ist? –

0

Ist Ihr ItemSerializer-Code korrekt? Der Rest sieht gut aus für mich.

Sie sollten 'Besitzer-ID' in Ihren Serializer-Feldern haben, denke ich.

Werfen Sie einen Blick auf diese Antwort, fügen Sie die verwandten Felder auf diese Weise hinzu.

https://stackoverflow.com/a/20636415/5762482

+0

Ich habe meinem Beitrag den zugehörigen Serializer hinzugefügt. –

+0

Sie sollten 'Besitzer-ID' in Ihren Serializer-Feldern haben, denke ich. – utkarshmail2052

+0

Wenn ich dem Serialisierungsprogramm "owner_id" hinzufüge, erhalte ich zur Laufzeit den folgenden Fehler: "Der Feldname' owner_id' ist für das Modell 'Item' nicht gültig." In meinem Modell heißt das Feld Besitzer, aber in der Datenbank ist es owner_id. –

1

Ihre Serializer nicht über ein Besitzerfeld und Ihrer Ansicht nach muss man nicht geben. Da es in Ihrem Modell nicht null ist, wird sich die DB beschweren.

sollten Sie die perform_update Sicht außer Kraft setzen und füge the owner as extra argument to the serializer

+0

Ich bin damit von meiner Tiefe. Wie müsste das perform_update aussehen, um den Eigentümer als Argument zum Serializer hinzuzufügen? –

+0

Es ist in der Dokumentation verlinkt erklärt - Sie müssen ein wenig scrollen und Sie werden ein Beispiel dafür haben. – Linovia

+0

Danke Linovia. –

1

Sie müssen die Ressource URI für das Feld zu übergeben, den Fremdschlüssel ist, hier Eigentümer ist der FK, so der

ownerIns = User.objects.get(id=2) 
let body = JSON.stringify({ url: 'fred', item_type: 'P', owner: ownerIns, owner_id: ownerIns.id }); 
Verwandte Themen