如何在不使用默认用户的情况下使用WishList分配UserProfile

时间:2018-07-08 09:03:43

标签: django django-models django-rest-framework django-views

我有一个包含模型UserProfile()的应用

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    city = models.CharField(max_length=50, default='')
    phone = models.IntegerField(default='0')
    image = models.ImageField(upload_to='profile_image', blank=True)

    def __str__(self):
        return self.user.username

连接到默认用户(用户)。我想将用户与愿望清单模型联系起来

class WishList(models.Model):
    toy_name_wish = models.ForeignKey(Toy, on_delete=models.CASCADE)
    user_wish = models.ForeignKey(UserProfile, on_delete=models.CASCADE)

    def __str__(self):
        return self.user_wish

并使用def post(self, request):的通用视图,我为玩具创建了简单的逻辑,该逻辑将在管理部分中显示为用户的愿望物品

class DetailToyView(TemplateView):
    template_name = 'app/detail_toy.html'
    #other defs

    def post(self, request, toy_id):
        toy = get_object_or_404(Toy, pk=toy_id)
        user_profile = UserProfile()
        wishlist = WishList() 
        try:
            selected_toy = get_object_or_404(Toy, pk=toy_id) 
    except(KeyError, Toy.DoesNotExist):
        return render(request, 'app/detail_toy.html', {'toy': toy})
    else:
        user_profile.user = self.request.user
        user = user_profile.user
        wishlist.toy_name_wish = toy
        wishlist.user_wish = user
        wishlist.save()
        return HttpResponseRedirect(reverse('app:detail-category-toy', args=(toy.id,)))

重要的是我的urls.py文件

from django.urls import path
from django.conf.urls import url
from . import views
from django.contrib.auth import views as auth_views

app_name = 'app'
urlpatterns = [
    path('', views.index, name='index'), # INDEX
    path('personal-page/', views.personal_page, name='personal-page'),
    # SIGN_IN, SIGN_OUT AND SIGN_UP
    path('sign-in/', auth_views.login,
        {'template_name': 'app/sign_in.html'},
        name='sign-in'),
    path('sign-out/', auth_views.logout,
        {'next_page': '/'},
        name='sign-out'),
    path('sign-up/', views.sign_up, name='sign-up'),
    # DETAIL_PAGES
    #url(r'^book-detail/(?P<book>[0-9]+)/$', views.detail_book, name='book'),
    url(r'^detail_category_toy/(?P<category_id>[0-9]+)/$', views.detail_category_toy, name='detail-category-toy'),
    url(r'^detail-toy/(?P<toy_id>[0-9]+)/$', views.DetailToyView.as_view(), name='toy')]

所以这是我单击按钮时遇到的问题

ValueError at /detail-toy/2/
Cannot assign "<SimpleLazyObject: <User: admin>>": "WishList.user_wish" must be a "UserProfile" instance.

这意味着我不能使用user.username 那么如何获取UserProfile实例而不是基本的User模型?

P.S:很抱歉有些愚蠢的变量

1 个答案:

答案 0 :(得分:1)

好吧,您的直接问题是将“用户”设置为“愿望清单”对象而不是“用户配置文件”。保存之前的行应为:

wishlist.user_wish = user_profile

但是实际上这里发生了很多奇怪的事情。一个用户只能有一个UserProfile,听起来不错,但是在此视图中,您始终创建一个新的UserProfile。如果该用户已经有一个配置文件,则将导致错误。而且您的WishList模型实际上不是列表,而是个人资料和玩具之间的单一关系。

您实际需要的是UserProfile和Toy之间的多对多关系,即愿望清单:

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    city = models.CharField(max_length=50, default='')
    phone = models.IntegerField(default='0')
    image = models.ImageField(upload_to='profile_image', blank=True)
    wishlist = models.ManyToManyField('Toy')

(而且您根本不需要WishList模型)

在您看来,使用get_or_create获取现有配置文件或创建一个新配置文件:

def post(self, request, toy_id):
    toy = get_object_or_404(Toy, pk=toy_id)
    user_profile = get_or_create(UserProfile, user=request.user)
    user_profile.wishlist.add(toy)
    return HttpResponseRedirect(reverse('app:detail-category-toy', args=(toy.id,)))