Django:根据字符串参数保存外键?

时间:2018-04-12 05:33:23

标签: django

这是事情。 分支机构可能包含许多产品。 表单会以字符串格式将pathbranch发布到产品模型。

获得发布的数据后,我怎么能像这样Product.objects.create(path="path1", branch="branch1")一样使用? 或者必须在forms.py?

中创建分支实例

这是错误的版本:它会引发ValueError: Cannot assign "'branch1'": "Product.branch" must be a "Branch" instance.

class Branch(models.Model):
    name = models.CharField(max_length=63, unique=True, blank=True)


class Product(models.Model):
    path = models.CharField(max_length=255)
    branch = models.ForeignKey(Branch, on_delete=models.CASCADE)

    def save(self, *args, **kwargs):
        kwargs['branch'], _ = Branch.objects.get_or_create(name=kwargs['branch'])
        super(Product, self).save(*args, **kwargs)

1 个答案:

答案 0 :(得分:1)

这不是保存问题。在将字符串赋值给分支名称期间会出错。如果要实现逻辑,请在保存之前执行

您可以使用python property来实现此目的,只需进行少量修改即可。不需要覆盖save方法。

models.py

class Branch(models.Model):
    name = models.CharField(max_length=63, unique=True)


class Product(models.Model):
    path = models.CharField(max_length=255)
    branch = models.ForeignKey(Branch, on_delete=models.CASCADE)

    @property
    def branch_name(self):
        return self.branch.name
    @branch_name.setter
    def branch_name(self, value):
        self.branch, _ = Branch.objects.get_or_create(name=value)

你的创建功能应该是

Product.objects.create(path="path1", branch_name="branch1")

注意:它是branch_name而不是branch。另外product.branch仍为branch对象,poduct.branch_name返回分支的名称。这也适用于更新。新product.branch_name branch更新了product

const users = [ { name: 'Samir', age: 27, favoriteBooks:[ {title: 'The Iliad'}, {title: 'The Brothers Karamazov'} ] }, { name: 'Angela', age: 33, favoriteBooks:[ {title: 'Tenth of December'}, {title: 'Cloud Atlas'}, {title: 'One Hundred Years of Solitude'} ] }, { name: 'Beatrice', age: 42, favoriteBooks:[ {title: 'Candide'} ] } ]; // Result: ['The Iliad', 'The Brothers Karamazov', 'Tenth of December', 'Cloud Atlas', 'One Hundred Years of Solitude', 'Candide']; var books = users .map(function(user) { return user.favoriteBooks; }) .map(function(book) { return book.title; }) .reduce(function(arr, titles) { return [ ...arr, ...titles ]; }, []); console.log(books);