Django:为模型设置多对多的值



我正在尝试测试我的型号ProjectCategoryTag。我在尝试向我的项目模型添加标记时遇到了一个问题。

它不允许我在Project模型中这样做,例如

self.project = Project.objects.create(
...
tags=Tag.objects.create("HTML5"),
)

Django文档建议我按如下方式执行。然而,我不能"添加";不保存模型的Tag和不添加Tag的情况下我无法保存模型

测试

class ProjectTests(TestCase):
def setUp(self):
self.tag = Tag.objects.create(name="HTML5")
self.project = Project(
title="Oaks on Main Shopping Center",
url="www.oaksonmain.co.za",
image=SimpleUploadedFile(
name="test-image.jpg",
content=open(
"static\images\test_images\florian-olivo-4hbJ-eymZ1o-unsplash (1).jpg", "rb"
).read(),
content_type="image/jpeg",
),
description="Beautiful website created for Oaks on Main Shopping Center in Knysna!",
category=Category.objects.create(name="Website"),
)
self.project.save() <- Problem here
self.project.tags.add(self.tag)  <- Problem here

def test_project_model(self):
self.assertEqual(f"{self.project.title}", "Oaks on Main Shopping Center")
self.assertEqual(f"{self.project.url}", "www.oaksonmain.co.za")
self.assertEqual(
f"{self.project.description}",
"Beautiful website created for Oaks on Main Shopping Center in Knysna!",
)
self.assertEqual(self.tags.count(), 3)
self.assertEqual(self.category.count(), 1)
self.assertEqual(self.image.count(), 1)
def test_project_listview(self):
resp = self.client.get(reverse("index"))
self.assertEqual(resp.status_code, 200)
self.assertContains(resp, self.project.title)
self.assertTemplateUsed(resp, "page/index.html")

型号

class Project(models.Model):
class Meta:
ordering = ["-id"]  # Always show latest projects first
verbose_name_plural = "Projects"
title = models.CharField(max_length=50)
url = models.URLField()
image = models.ImageField(upload_to=f"{title}/")
description = models.TextField()
category = models.ForeignKey("Category", on_delete=models.PROTECT, related_name="categories")
tags = models.ManyToManyField("Tag", verbose_name="tags")
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("index")

class Category(models.Model):
class Meta:
ordering = ["name"]
verbose_name_plural = "Categories"
name = models.CharField(max_length=20)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("index")

class Tag(models.Model):
class Meta:
ordering = ["name"]
verbose_name_plural = "Tags"
name = models.CharField(max_length=10)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("index")

您可以首先保存标记或模型对象,然后将标记链接为该Projecttags之一,因此:

html5_tag, __ = Tag.objects.get_or_create(name='HTML5')
self.project = Project.objects.create(
# no tags=…
)
self.project.tags.add(html5_tag)

您的ImageField还应该使用upload_to=…参数的可调用,因此:

class Project(models.Model):
# …
defupload_image(self, filename):
return f'{self.title}/{filename}'
image = models.ImageField(upload_to=upload_image)
# …

最新更新