对不起,答案很长。从你的代码来看,我假设你是 Django 的新手,所以这个答案希望能提供信息以及在过程中回答问题。
用户
在您的审查模型中,user
应该是 aForeignKey
而不是 a CharField
。我知道存储用户名似乎更自然,特别是如果您将自己查看数据库表,但是这种方法容易出错,除非您有充分的理由,否则这是一件坏事。
假设您有一个用户名为foousername
. 然后该用户创建了几个评论。因此,此时您将有几个评论该user
字段的位置foousername
。现在,如果用户想要将他/她的用户名更改为someotherfoousername
,为了不破坏评论和用户之间的链接,您必须更改user
用户创建的所有评论的字段以使用新用户名。这是一个额外的步骤,您可能会忘记这样做,因此容易出错。使用ForeignKey
立即解决了这个问题。即使用户更改了他/她的用户名,用户的主 id 也不会改变,因此如果评论链接到主键(即外键),则不必更新评论。所以工作量更少,方法更可靠。
所以这样做(related_name
接下来会解释):
user = models.ForeignKey(User, related_name='reviews')
related_name
当您使用related_name
Django 时,您的生活会轻松很多。
考虑你的观点。首先查询产品。然后,一旦你得到它,你就得到它的 id,然后你构造一个查询,它将返回该产品的所有评论。使用 Django,您可以使用更少的代码完成所有这些工作。
product = get_object_or_404(Productbackup, url_friendly=product_name)
reviews = product.reviewbackup_set.all()
_set
然而,由于整个业务,这有点令人困惑。这就是related name
进来的地方。如果您将product
字段定义如下:
product = models.ForeignKey(Productbackup, related_name='reviews')
那么你可以以更易读的方式做同样的事情(并且 Python 应该是可读的......):
reviews = product.reviews.all()
用户资料
外键允许实现一对多的关系。因此,对于产品和评论来说,这是非常有意义的。一个产品可以有很多评论。但是,用户配置文件通常不是这种情况。通常一个用户只有一个用户配置文件。因此,在您的用户配置文件中,您不应该ForeignKey
对用户使用,而是应该OneToOneField
像这样使用:
user = models.OneToOneField(User, primary_key=True, related_name='profile')
这使您可以轻松访问用户的个人资料:
user_profile = User.objects.get(...).profile
用户画像
对于每条评论,现在由于用户ForeignKey
按照我的第一个解释,您可以非常轻松地访问用户的图像:
review = Reviewbackup.objects.all()[0]
user_image = review.user.profile.image # <- see, very easy
图片网址
每当您FileField
在 Django 中使用时,它都会将文件上传到upload_to
您的媒体文件夹下——MEDIA_ROOT
在您的项目设置中定义的那个。因此,在您的情况下,Django 会将图像存储images
在您的媒体文件夹中的文件夹中。此外,如果您配置MEDIA_URL
,则允许访问文件的 url,例如:
user_profile.image.url
硬编码的 URL
在模板中包含直接 url 是一个非常糟糕的主意。这就是 url 模式名称的用途。所以想法是您为 url 模式分配一个名称,以便稍后您通过引用名称来获取 url。这使得代码更易于维护。例如,以下是用户的 url 模式:
url(r'^user/(?P<username>\w+)/$', 'user_view', name='user_view')
这允许您在模板中像这样使用它:
{% load url from future %}
link: <a href="{% url 'user_view' username=user.username %}">{{ user.username }}</a>
把所有东西放在一起
# views.py
def view_reviews(request, product_name):
product = get_object_or_404(Productbackup, url_friendly=product_name)
reviews = product.reviews.all().order_by("-created_on")
return render_to_response('reserve/templates/view_reviews.html',
{'reviews':reviews},
context_instance=RequestContext(request))
和
# models.py
class Reviewbackup(models.Model):
review = models.CharField('Review', max_length = 2000)
user = models.ForeignKey(User, related_name='reviews')
rating = models.IntegerField(max_length=2, choices=RATING_OPTIONS)
product = models.ForeignKey(Productbackup, related_name='reviews')
def __unicode__(self):
return self.review
class UserProfile(models.Model):
user = models.OneToOneField(User, primary_key=True, related_name='profile')
image = models.ImageField(blank=True, null=True, max_length=255, upload_to="images/")
和
{# template #}
{% load url from future %}
{% for review in reviews %}
<br><a href="{% url user_view username=review.user.username %}">
{{ review.user.username }}</a><br>
<img class="thumbnail" src="{{ review.user.profile.image.url }}"><br>
{{ review.review }}
{% endfor %}