Fremdschlüssel speichern

Django, Flask, Bottle, WSGI, CGI…
Antworten
Vinter
User
Beiträge: 8
Registriert: Sonntag 10. März 2019, 16:22

Hallo!

Ich bastel mir gerade mit Django ein kleines Tool, das aus einer MySQL-Datenbank mit Videospielen Tabellen in BBCode erzeugt. Sprich: Ich lege über den Browser neue Datensätze an und das Tool spuckt mir am Ende einen fertigen BBCode raus, den ich nur noch per Copy/Paste in ein Forum posten muss.

Im Rahmen meines Problems kann man sich das Ganze aber schlicht als Bibliothek vorstellen: Es gibt Messen ("Events"), zu jeder Messe gehören mehrere Videospiele und zu jedem Videospiel gehören 1 bis n Trailer. Da ein Spiel mehrere Trailer haben kann, ein Trailer aber immer nur zu einem konkreten Spiel gehört, habe ich hier einen Fremdschlüssel benutzt.

Mein Problem: Wenn ich einen neuen Trailer anlegen möchte, habe ich ein forms.ChoiceField, über das ich das dem Trailer zugehörige Videospiel auswählen möchte. Beim Speichern erhalte ich jedoch
Exception Type: ValueError
Exception Value:
Cannot assign "'a961cc78-f93a-4a1a-9fbb-4648ce0f0366'": "Trailer.game_id" must be a "Game" instance.
Hier einmal die relevanten Models

Code: Alles auswählen

class Game(models.Model):
    game_id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text='primary_key for games')
    game_name = models.CharField(max_length=200, help_text='Spieltitel', unique=True)
    release_date = models.CharField(max_length=200, help_text='Release')
    platforms = models.ManyToManyField('Platform', help_text='Spiel') #One game can be on multiple platforms and one platform can have multiple games
    events = models.ManyToManyField('Event')

    def __str__(self):
        """Return game_name instead (unidentifiable) game_id."""
        return self.game_name

    def display_platforms(self):
        """ Create a string for platforms. """
        return ', '.join(Platform.platform_name for Platform in self.platforms.all())

    def display_events(self):
        return ', '.join(Event.event_name for Event in self.events.all())

        display_platforms.short_description = 'Platform'
        
class Trailer(models.Model):
    trailer_id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text='primary_key for trailer')
    game_id = models.ForeignKey('Game', on_delete=models.SET_NULL, null=True)   #One Trailer has one game, but one game can have multiple trailer
    trailer_url = models.CharField(max_length=200, help_text='Trailer URL')
    trailer_name = models.CharField(max_length=200, help_text='Trailer Name')

    def __str__(self):
        return self.trailer_name
Darauf basierend habe ich eine Form NewTrailerForm

Code: Alles auswählen

class NewTrailerForm(forms.Form):

    # Query all games belonging to the current event
    current_event = Event.objects.filter(current_event="True")
    que = Game.objects.filter(events = current_event.values()[0]['event_id'])

    game_choices = [[game.game_id, game.game_name] for game in que]
    game = forms.ChoiceField(choices = game_choices, required=True)

    trailer_name = forms.CharField(max_length=200, required=True)
    trailer_url = forms.CharField(max_length=200, required=True)
Und eine View

Code: Alles auswählen


def NewTrailerView(request):

    trailer = Trailer()
    game = Game()

    if request.method == 'POST':

        form = NewTrailerForm(request.POST)

        if form.is_valid():
        
            trailer.trailer_name = form.cleaned_data['trailer_name']
            trailer.trailer_url = form.cleaned_data['trailer_url']
            trailer.game_id = form.cleaned_data['game']
            

            trailer.save()

        return HttpResponseRedirect(reverse('trailer') )

    else:

        form = NewTrailerForm()

        context = {

        'form': form,
        'trailer': trailer,
        }

        return render(request, 'catalog/newtrailer.html', context)

Die Zeile

Code: Alles auswählen

trailer.game_id = form.cleaned_data['game']
meckert er mit der oben genannten Fehlermmeldung an.

Wie lautet des Rätsels Lösung? Danke schon mal für eure Hilfe!
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

Die Fehlermeldung ist offensichtlich. `models.ForeignKey` erwartet eine Instanz der Klasse `Game` wie du es hier initialisiert hast:

Code: Alles auswählen

class Trailer(models.Model):
    ...
    game_id = models.ForeignKey('Game', on_delete=models.SET_NULL, null=True)   #One Trailer has one game, but one game can have multiple trailer
Du versuchst der Klasse allerdings einen einfachen String zu übergeben. Übergebe `trailer.game_id` die `Game`-Instanz damit du den "ForeignKey" der anderen Entität abgreifen kannst.
When we say computer, we mean the electronic computer.
Antworten