Django在两个模型上形成验证和操作

时间:2013-11-02 12:03:27

标签: django django-forms

我在构建自定义表单(仅默认模型表单)方面没有太多经验,我在这里寻求帮助。我正在尝试构建一个将从用户获取“feed_url”的表单,如果它已经存在,只需将引用添加到UserFeed模型中。如果它不存在,它应该将它添加到Feed模型,并在UserFeed模型中也引用它。

模型

class Category(models.Model):
    name = models.CharField(unique=False, max_length=64)
    user = models.ForeignKey(User)
    slug = AutoSlugField(populate_from='name', always_update='True', unique_with='user')


    def __unicode__(self):
        return self.name

    class Meta:
        ordering = ('name',)


class Feed(models.Model):
    feed_url = models.URLField(unique=True)

    def __unicode__(self):
        return self.feed_url


class UserFeed(models.Model):
    feed = models.ForeignKey(Feed)
    title = models.CharField(max_length=64)
    category = models.ForeignKey(Category)
    user = models.ForeignKey(User)
    slug = AutoSlugField(populate_from='title', always_update='True', unique_with='user')

    def __unicode__(self):
        return self.title

    class Meta:
        ordering = ('title',)

形式

class UserFeedForm(forms.Form):
    feed_url = forms.URLField()
    title = forms.CharField(max_length=64)
    category = forms.ModelChoiceField(Category)
    user = forms.HiddenInput()

视图

def addfeed(request):
    categories = Category.objects.filter(user=request.user)
    feeds = Feed.objects.all()
    if request.method == 'POST':
        form = UserFeedForm(request.POST)
        form.fields['category'].queryset = categories
        if form.is_valid():
            feed = form.save(commit=False)
            if form.fields['feed_url'] in feeds:
                ##### add to Feed object and add reference to UserFeed object
                feed.user = request.user
                feed.save()
            else:
                ##### get id from Feed object and add reference to UserFeed object
                feed.user = request.user
                feed.save()
            return HttpResponseRedirect("/reader/manage")
    else:
        form = UserFeedForm()
        form.fields['category'].queryset = categories
    context = {'form': form,}
    return expand_context_and_render(request, context, 'reader/form.html')

有人可以指出我正确的方向吗? 感谢

更新 现在我更新了我的观点和表格如下:

形式

class UserFeedForm(forms.ModelForm):
    feed = forms.URLField()
    title = forms.CharField(max_length=64)
    category = forms.ModelChoiceField(Category)
    user = forms.HiddenInput()

    class Meta:
        model = UserFeed
        fields = ['feed', 'title', 'category']

视图

def addfeed(request):
    categories = Category.objects.filter(user=request.user)
    feeds = Feed.objects.all()
    if request.method == 'POST':
        form = UserFeedForm(request.POST)
        form.fields['category'].queryset = categories
        if form.is_valid():
            feed = form.cleaned_data.get('feed')
            if feed in feeds:
                ##### get id from Feed and add reference to UserFeed
                existing_feed = Feed.objects.get(feed_url=feed)
                form.feed = existing_feed.id
                form.user = request.user
                form.save(commit=True)
            else:
                ##### add to Feed object and then add reference to UserFeed object
                Feed.object.create(feed_url=feed)
                existing_feed = Feed.objects.get(feed_url=feed)
                form.feed = existing_feed.id
                form.user = request.user
                form.save(commit=True)
            return HttpResponseRedirect("/reader/manage")
    else:
        form = UserFeedForm()
        form.fields['category'].queryset = categories
    context = {'page_title': page_title,
               'form': form,
               }
    return expand_context_and_render(request, context, 'reader/form.html')

我想我越来越近但它仍然无效,给我这个错误: “无法指定”u'http://feeds.bbci.co.uk/news/rss.xml'“:”UserFeed.feed“必须是”Feed“实例。”

任何想法我该如何解决这个问题? 感谢

3 个答案:

答案 0 :(得分:0)

尝试在文档中查看此questioninline formsets

此外,在您的UserFieldForm中,feed被定义为URLField。所以在你看来,在这一行:

feed = form.get_cleaned_data.get('feed')

您的Feed变量只是一个字符串,而不是Feed对象。这可能是您的错误发生的地方?那是inline formsets可以帮助你的地方。此外,此行还会使您的if feed in feeds:语句失败,因为feed只是一个字符串,而feeds是所有Feed实例的Queryset。我认为这会导致您的观点始终以else块结束?

我自己是Django的新手,但我希望这可以帮助你。

答案 1 :(得分:0)

您正在寻找的逻辑是:

  1. 检查Feed是否存在。
  2. 如果存在,请抓取它。
  3. 如果它没有创建新的Feed。
  4. 将Feed与UserFeed对象相关联。
  5. get_or_create方法执行第1-3部分,因此您需要以下内容:

    if form.is_valid():
        obj = form.save(commit=False)
        feed = form.cleaned_data.get('feed')
        feed_obj, created = Feed.objects.get_or_create(feed_url=feed)
        obj.feed = feed_obj
        obj.save()
        return HttpResponseRedirect("/reader/manage")
    

答案 2 :(得分:0)

我终于得到了这样的工作:

形式

class UserFeedForm(forms.Form):
    feed = forms.URLField()
    title = forms.CharField(max_length=64)
    category = forms.ModelChoiceField(Category)
    user = forms.HiddenInput()

    class Meta:
        model = UserFeed
        fields = ['feed', 'title', 'category']

视图

def addfeed(request):
    user = request.user
    categories = Category.objects.filter(user=request.user)
    if request.method == 'POST':
        form = UserFeedForm(request.POST)
        form.fields['category'].queryset = categories
        if form.is_valid():
            feed = form.cleaned_data['feed']
            category = form.cleaned_data['category']
            title = form.cleaned_data['title']
            feed_obj, created = Feed.objects.get_or_create(feed_url=feed)
            obj = UserFeed(feed=feed_obj, title=title, category=category, user=user)
            obj.save()
        return HttpResponseRedirect("/reader/manage")
    else:
        form = UserFeedForm()
        form.fields['category'].queryset = categories
    context = {'page_title': page_title,
               'form': form,
               }
    return expand_context_and_render(request, context, 'reader/form.html')

以下答案中的两个提示都指向了正确的方向。谢谢!