将一个模型连接到另一个

时间:2015-05-01 11:42:49

标签: django django-models

我试图在没有流行模块的情况下为自己做一个简单的商店。并堆叠下一件事。

我有两个模型 - 文章(类似于"产品"在这里)和具有自定义配置文件模型的用户。所以我需要的是当用户进入文章页面时,他可以按下按钮("购买"也许)并且该文章模型连接到用户。所以他可以在他的个人资料页面上看到它。另外,我需要在模板中使用检查功能,表示用户是否购买了文章(某种" if-else")。

我已经使用ForeignKey将我的文章模型连接到我的用户个人资料模型,但是现在我不知道下一个要移动的位置。有人可以帮忙吗?

我的模型userprofile

    import PIL

    from django.db import models
    from django.contrib.auth.models import User
    from PIL import Image
    from django.db import models
    from article.models import Article

    class UserProfile(models.Model):  
        user = models.OneToOneField(User)
        user_picture = models.ImageField(upload_to='users', blank=False, null=False, default='users/big-avatar.jpg')
        user_balance = models.IntegerField(default=0)
        user_articles = models.ForeignKey(Article, blank=True, null=True)

    User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u) [0])

我的forms.py userprofile

from django import forms
from userprofile.models import User
from userprofile.models import UserProfile

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ('email', 'first_name', 'last_name',)

class UserProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ('user_picture', 'user_balance')

我对userprofile

的看法
from django.shortcuts import render, render_to_response, redirect
from django.shortcuts import HttpResponseRedirect, Http404, HttpResponse
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from django.core.context_processors import csrf

from userprofile.forms import User
from userprofile.forms import UserForm
from userprofile.forms import UserProfileForm

def userprofile(request, username):
    u = User.objects.get(username=username)
    if request.POST:
        user_form = UserForm(request.POST, instance=request.user)
        user_profile = UserProfileForm(request.POST, request.FILES, instance=request.user.profile)
        if user_form.is_valid() and user_profile.is_valid():
            user_form.save()
            user_profile.save()
    else:
        user_form = UserForm(instance=request.user,
            initial={
                'first_name': request.user.first_name,
                'last_name': request.user.last_name,
                'email': request.user.email,
            })
        user = request.user
        profile = user.profile
        user_profile = UserProfileForm(instance=profile)

    return render_to_response('profile.html', {'user_form': user_form, 'user_profile': user_profile}, context_instance=RequestContext(request))

我的模型article需要连接起来:

import PIL

from django.db import models
from django.contrib.auth.models import User
from PIL import Image
from django.db import models

class Article(models.Model):
    class Meta():
        db_table = 'article'

    article_title = models.CharField(max_length=200, blank=False, null=False)
    article_anchor = models.CharField(max_length=200, blank=False, null=False)
    article_image = models.ImageField(upload_to='items', blank=False, null=False)
    article_users = models.IntegerField(default=0)

class Comments(models.Model):
    class Meta():
        db_table = 'comments'

    comments_date = models.DateTimeField()
    comments_text = models.TextField(verbose_name=u'')
    comments_article = models.ForeignKey(Article)
    comments_from = models.ForeignKey(User)

1 个答案:

答案 0 :(得分:2)

只是为了澄清一些事情:

  1. 我假设用户可以购买多篇文章
  2. 文章可以属于许多用户
  3. 如果是这种情况,那么您在用户模型和文章模型之间存在多对多关系。所以你可以做的是修改你的文章模型:

    class Article(models.Model):
        class Meta():
            db_table = 'article'
    
        article_title = models.CharField(max_length=200, blank=False, null=False)
        article_anchor = models.CharField(max_length=200, blank=False, null=False)
        article_image = models.ImageField(upload_to='items', blank=False, null=False)
        article_users = models.ManyToManyField(User) # <- use ManyToManyField instead of IntegerField
    

    另一种方法是创建一个OrderHistory模型来存储谁(User)购买了什么(文章):

    class OrderHistory(models.Model):
        user = models.ForeignKey(User)
        article = models.ForeignKey(Article)
        purchase_date = models.DateTimeField(auto_now_add=True)
    

    我们假设您使用了第一种方法。修改模型是不够的。您需要向网站添加一些内容:

    1. 用于显示供购买用户的文章列表的网页

      • 因此,您需要一个显示可用文章列表的模板文件
      • 您需要一个视图功能来呈现此页面
      • 此页面将包含文章列表以及用户通过复选框选择要购买的文章的方式(或每篇文章旁边的许多购买按钮,您的选择)。因此,基本上,您的模板将包含一个包含文章列表的元素和一个将此数据发回服务器的“购买”按钮
    2. 当用户点击“购买”按钮时,数据会提交到您需要在 urls.py

      中定义的网址
      • 在您的urls.py中添加一个新网址并将其挂钩到视图功能
      • view函数将使用request.user来识别它是哪个用户,并使用request.POST中的数据来确定正在购买的文章ID。
      • 然后您需要使用

        从数据库中找到该文章
        article = Article.objects.filter(pk=the_id_you_received_from_POST) 
        article.article_users.add(request.user)
        article.save()
        
    3. 返回成功消息
    4. 在开始之前阅读此链接:

      https://docs.djangoproject.com/en/1.8/topics/db/examples/many_to_many/

      编辑: 正如Daniel指出的那样,从UserProfile中删除以下行     user_articles = models.ForeignKey(Article,blank = True,null = True)

      您必须考虑用户与文章之间的关系是一对多还是多对多。 models.ForeignKey意味着一个用户可以购买很多文章,但是一旦购买了一篇文章,它就只能属于一个用户。(这可能不是你想要的)

      要将数据从网页传递到您的视图功能,有两种方法:

      1. 通过GET请求:参数被附加到网址的末尾,这是一个很好的例子,说明如何在Django中完成:Capturing url parameters in request.GET

      2. 通过POST请求:通常,您将在页面上有一个表单,并提交一个提交按钮以将数据提交到预定义的URL:

        <form action = "url_for_handling_POST_request" method = "post">
        
      3. 请关注Django的教程: - https://docs.djangoproject.com/en/1.8/intro/tutorial04/ - https://docs.djangoproject.com/en/1.8/topics/forms/#processing-the-data-from-a-form

        在您的情况下,您应该使用POST请求。请阅读上面的文档。它包含一个与您需要的匹配的示例。

        注意:不要忘记在表单中插入CSRF令牌,否则Django会抱怨:

            <form ...>
                {% csrf_token %}
            </form>