Не удается сохранить запись из Django Модель - PullRequest
1 голос
/ 09 января 2020

Я изменяю запись в базе данных sqlite3, используя Django, и функция save (), похоже, не работает.

Однако я могу сохранить изменения с помощью графического приложения администратора.

Вот код указанной c модели, в которой я пытаюсь сохранить:

 def pickup(self,item):
        room_items = Item.objects.filter(roomID = self.room.id)
        items = [ri.item_name for ri in room_items]

        if item in items:
            i = Item.objects.filter(item_name = item)
            i[0].roomID = 0
            i[0].playerID = self.id
            i[0].save()
            return f'{self.name} picked up the {item} from {self.room}'
        else:
            return f"{item} is not in the room. can't pick it up."

функция захвата находится в классе с именем Player. Я обновляю запись Item. Любые решения?

Вот весь файл моделей для тех, кто хочет больше контекста:

from django.db import models
import string,random

class Room(models.Model):
        ### Field Columns in Room Table ###
    room_name = models.CharField(max_length = 64)
    description = models.CharField(max_length=500, default=f"No Room description'" )
    up = models.CharField(max_length = 64, default="")
    down = models.CharField(max_length = 64, default="")
    left = models.CharField(max_length = 64, default="")
    right = models.CharField(max_length = 64, default="")

    def items(self):
        items = Item.objects.filter(roomID = self.id)
        return [i.item_name for i in items]

    def __str__(self):
        return self.room_name

class Player(models.Model):
    # uuid = models.UUIDField(default=uuid.uuid4, unique=True)
    HP = models.IntegerField(default=10)
    name = models.CharField(max_length=64, default=f"Room {random.choice(string.ascii_letters)}")#attempting to generate a random room name using ascii_letters from string library and random.choice()
    room = models.ForeignKey(Room, on_delete=models.CASCADE, null=True)
    # inventory = models.ForeignKey(Inventory)

    def inventory(self):
        inventory = Item.objects.filter(playerID = self.room.id)
        return [i.item_name for i in inventory]

    def pickup(self,item):
        print(self.room.id)
        room_items = Item.objects.filter(roomID = self.room.id)
        items = [ri.item_name for ri in room_items]

        if item in items:
            i = Item.objects.filter(item_name = item)
            i[0].roomID = 0
            i[0].playerID = self.id
            i[0].save()
            i[0].persist()
            return f'{self.name} picked up the {item} from {self.room}'
        else:
            return f"{item} is not in the room. can't pick it up."

    def drop_item(self,item):
        pass

    def initialize(self,start):
        # start = input(f"{self.name}, you are outside the PyTower. It is a 10 story tower. There is a treasure chest on the top floor. Do you have what it takes to reach the top??? type 'y' to enter Pytower: ")

        if start == 'y':
            self.room = Room.objects.get(room_name = "Foyer")
            print(f"{self.name}, you have now entered the {self.room.room_name}")
            return f"{self.name}, you have now entered the {self.room.room_name}"
        else:
            print(f"{self.name}, when you're ready for Pytower, you may enter!")
            return f"{self.name}, when you're ready for Pytower, you may enter!"

        print(self.room.description)
        print('in room: ', self.room, 'up:',self.room.up, 'down:',self.room.down, 'left:',self.room.left, 'right:', self.room.right)
        return self.room

    def move(self,way=""):
        # print(self.room[way])  #causes error, Room object not subscriptable
        # print(way)
        # if self.room[way]:
        #     pass
        if way == 'up':
            if not self.room.up:
                print('you cannot go that way. no rooms there...')
                return 'you cannot go that way. no rooms there...'
            else:
                self.room = Room.objects.get(room_name = self.room.up)
                print('in room: ', self.room, 'up:',self.room.up, 'down:',self.room.down, 'left:',self.room.left, 'right:', self.room.right)
                return self.room

        elif way == 'down':
            if not self.room.down:
                print('you cannot go that way. no rooms there...')
                return 'you cannot go that way. no rooms there...'
            else:
                self.room = Room.objects.get(room_name = self.room.down)
                print('in room: ', self.room, 'up:',self.room.up, 'down:',self.room.down, 'left:',self.room.left, 'right:', self.room.right)
                return self.room

        elif way == 'left':
            if not self.room.left:
                print('you cannot go that way. no rooms there...')
                return 'you cannot go that way. no rooms there...'
            else:
                self.room = Room.objects.get(room_name = self.room.left)
                print('in room-', self.room, 'up-',self.room.up, 'down-',self.room.down, 'left-',self.room.left, 'right-', self.room.right)
                return self.room

        elif way == 'right':
            if not self.room.right:
                print('you cannot go that way. no rooms there...')
                return 'you cannot go that way. no rooms there...'
            else:
                self.room = Room.objects.get(room_name = self.room.right)
                print('in room: ', self.room, 'up:',self.room.up, 'down:',self.room.down, 'left:',self.room.left, 'right:', self.room.right)
                return self.room

        else:
            print('you have entered an invalid direction')
            return 'you have entered an invalid direction'

    def __str__(self):
        if not self.room:
            return  f"{self.name} is outside." 
        else:
            return f"{self.name} in {self.room}"

class Item(models.Model):
    item_name = models.CharField(max_length=64)
    strength = models.IntegerField(default=5)
    item_type = models.CharField(max_length=64,default="weapon")
    # playerID = models.ForeignKey(Player, on_delete=models.CASCADE, null=True)
    # roomID = models.ForeignKey(Room, on_delete=models.CASCADE, null=True)
    playerID = models.IntegerField(blank=True,null=True)
    roomID = models.IntegerField(default=1,null=True,blank=True)

    def persist(self):
        self.save()

    def __str__(self):
        return self.item_name

1 Ответ

1 голос
/ 09 января 2020

Чтобы понять, почему ваша модель не сохраняется, вы должны сначала понять , как оцениваются наборы запросов . По сути, каждый раз, когда вы итерируете над ними или срезаете их, они попадут в базу данных, однако есть предостережения по этому поводу.

Рассмотрим следующий абстрактный пример:

def MyModel(models.Model):
    column = models.IntegerField()

>>> MyModel.objects.create(column=1)
<MyModel: MyModel object (1)>
>>> queryset = MyModel.objects.all()

Нарезка:

>>> queryset[0].column = 2
>>> queryset[0].save()
>>> queryset[0].column
1

В приведенном выше примере я взял срез, например. queryset[0], который попадает в базу данных, затем сразу же взял второй срез , чтобы попытаться сохранить внесенные изменения, которые попадают в базу данных во второй раз. Наконец, я взял третий срез, который снова попадает в базу данных.

Поскольку первый срез не является тем же объектом , что и объект, который я назвал .save(), изменения не отражаются в базе данных. Чтобы это исправить, просто сохраните ссылку на слайс как переменную:

>>> instance = queryset[0]
>>> instance.column = 2
>>> instance.save()
>>> instance.column
2

В этом примере я обращаюсь к базе данных только дважды: один раз при вызове instance = queryset[0], и во второй раз в instance.save().

Вот оптимизированная версия вашего кода:

def pickup(self, item_name):
    items = Item.objects.filter(item_name=item_name, roomID=self.room.id)

    if items:
        item = items[0]
        item.roomID = 0
        item.playerID = self.id
        item.save()
        return 'message'

    return 'no item'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...