對不起,很長的答案。根據你的代碼判斷,我認爲你是Django的新手,所以這個答案希望能夠在過程回答問題中提供信息。
用戶
在您的審查模式,user
應該是ForeignKey
而不是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
圖片URL
每當你在Django使用FileField
,它上傳文件到在你的媒體文件夾upload_to
的地方 - 在您的項目設置中MEDIA_ROOT
定義的。所以在你的情況下,Django會將圖像存儲在媒體文件夾中的images
文件夾中。此外,如果您配置MEDIA_URL
,允許訪問像文件的URL:
user_profile.image.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/")
一個d
{# 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 %}
感謝您的全面回答!當我將用戶從CharField更改爲ForeignKey時,當我運行遷移時(我正在使用South)時出現錯誤:以下SQL查詢失敗:CREATE INDEX「reserve_reviewbackup_fbfc09f1」ON「reserve_reviewbackup」(「user_id」); 錯誤是:索引reserve_reviewbackup_fbfc09f1已經存在 !在實際遷移過程中發現錯誤!中止。 !由於您的數據庫不支持運行 !交易中的模式變更聲明,我們有 !使其處於移民之間的臨時狀態。 – sharataka
很抱歉聽到這個消息。不知道如何解決它。在數據庫中有多少數據?如果開發數據庫/部署,則可以從頭開始(從頭開始執行syncdb),確保新的數據庫模式正常工作,然後在所有調試和錯誤修復後遷移舊數據。 – miki725