Цепочка update и get метод в Django для обновления полей - PullRequest
0 голосов
/ 05 марта 2019

У меня есть Django Model следующим образом:

class IPGroup(models.Model):
    name = models.CharField(max_length=50, unique=True)
    junos_space_id = models.CharField(max_length=50)

class Jira(models.Model):
    jira_id = models.CharField(max_length=50, unique=True)
    ip_groups = models.ForeignKey(IPGroup, null=True, on_delete=models.SET_NULL)

Теперь у меня есть атомарная транзакция ORM следующим образом:

try:
    with transaction.atomic(): 
        IPGroup.objects.filter(id=2).update(junos_space_id=3)
        Jira.objects.filter(jira_id=2)).update(ip_groups_id=2)
except Exception:
    response = Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR,
                        data={'status': 'Database error encountered'})

Это работает хорошо, когда все в порядке. Однако когдавозникает ошибка, как в случае неправильного идентификатора, filter просто дает пустой набор запросов, и он никогда не попадает в исключение.

Я пытался переписать его с get вместо фильтра следующим образом:

try:
    with transaction.atomic(): 
        IPGroup.objects.get(id=2).update(junos_space_id=3)
        Jira.objects.get(jira_id=2)).update(ip_groups_id=2)
except Exception:
    response = Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR,
                        data={'status': 'Database error encountered'})

Но это дает мне следующую ошибку атрибута:

AttributeError: объект 'IPGroup' не имеет атрибута'update'

Каков наилучший способ сделать это чистым способом?

Ответы [ 2 ]

3 голосов
/ 05 марта 2019

Вам нужно будет разбить код на 3 шага

  1. сначала get, затем следующее обновление

     ip_group = IPGroup.objects.get(id=2)
    
  2. Обновить поле

     ip_group.junos_space_id=3
    
  3. сохранить

     ip_group.save()
    

для справки документы

1 голос
/ 05 марта 2019

К счастью, update() возвращает количество строк, соответствующих запросу , поэтому, если вы хотите использовать .update() вместо загрузки, обновления и сохранения объекта, как подсказывает ответ @ AJS, вы может сделать что-то вроде

try:
    with transaction.atomic():
        if IPGroup.objects.filter(id=2).update(junos_space_id=3) == 0:
            raise ValueError("No IPGroups matched")
        if Jira.objects.filter(jira_id=2).update(ip_groups_id=2) == 0:
            raise ValueError("No Jiras matched")
except Exception as exc:
    response = Response(
        status=status.HTTP_500_INTERNAL_SERVER_ERROR,
        data={"status": "Database error encountered: %s" % exc},
    )
...