【问题标题】:Submit to form without relying on URL不依赖 URL 提交表单
【发布时间】:2016-06-20 12:25:09
【问题描述】:

好吧,看来我在这个小任务上有点过头了。我想问一下如何在不依赖 URL 值的情况下提交表单?

在我的示例中,用户必须先登录才能看到他们的图库图片。确定这一点是通过“上下文”来确定的,该上下文分配了活动用户(如已登录)。向@chem1st 和@Daniel-Roseman 提供帮助,以帮助我昨天解决这个问题。现在它可以在他们登录后在主页显示他们自己的用户画廊。

我不喜欢使用“blahblah.com/bobby/upload”上传,因为它看起来不太安全。我想让登录用户通过“blahblah.com/upload/”上传。这意味着 view.py 中的表单必须以某种方式获取登录用户的上下文,并将数据保存到该帐户下的数据库中。

我一直在玩弄,并寻找答案,但找不到任何东西。有人可以帮我指出正确的方向吗?

这是我的models.py

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    activation_key = models.CharField(max_length=40, blank=True)
    key_expires = models.DateTimeField(default=datetime.date.today())

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

    class Meta:
        verbose_name_plural='User profiles'


class ImageDoc(models.Model):
    user = models.ForeignKey(UserProfile)
    imgfile = models.ImageField(upload_to='images/')

forms.py:

class RegistrationForm(UserCreationForm):
    email = forms.EmailField(required=True, widget=forms.TextInput(attrs={'placeholder': 'E-mail address'}))
    first_name = forms.CharField(required=True)
    last_name = forms.CharField(required=True)


    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email', 'username', 'password1', 'password2')


    class ImgDocForm(forms.Form):
        user_file = forms.ImageField()


    def clean_user_file(self, *args, **kwargs):
        cleaned_data = super(ImgDocForm,self).clean()
        user_file = cleaned_data.get("user_file")

        if user_file:
            if user_file.size > 5 * 1024 * 1024:
                raise forms.ValidationError("Filesize is too big.")

            if not os.path.splitext(user_file.name)[1].strip().lower() in ['.jpg','.png','.gif','.jpeg']:
                raise forms.ValidationError("File does not look like as picture.")

        return user_file


    class UserForm(forms.Form):
        class Meta:
            model = User
            fields = ['first_name', 'last_name', 'password', 'email', 'username']

我的 views.py 文件(编辑:更改了索引以显示用户详细信息、图库和快速上传功能):

def sign_in(request):
    context = RequestContext(request)

    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(username=username, password=password)

        if user:
            if user.is_active:
                login(request, user)
                return HttpResponseRedirect('/', context)
            else:
                return HttpResponse("Verify your account!")
        else:
            return HttpResponse("Invalid login details supplied.")


def populateContext(request, context):
    context['authenticated'] = request.user.is_authenticated()
    if context['authenticated'] == True:
        context['username'] = request.user.username


def index(request):
    user_details = UserProfile.objects.get(user=request.user)
    gallery = ImageDoc.objects.filter(user_id=request.user.id)

    if request.method == 'POST':
        form = ImgDocForm(request.POST, request.FILES)
        if form.is_valid():
            origin_form = form.cleaned_data["user_file"]
            origin_name = origin_form.name

            original_name = ImageDoc(user_id=request.user.id, imgfile=origin_name)
            original_name.save()

            return HttpResponse('Saved!')
    else:
        form = ImgDocForm()

    documents = ImageDoc.objects.all()

    return render(request, 'test.html', {'documents': documents, 'form': form, 'user_details': user_details, 'gallery': gallery})




def upload(request):
    data = {}
    thumb_size = (100,100)
    micro_thumb_size = (50,50)

    if request.method == 'POST':
        userform = ImgDocForm(request.POST, request.FILES)

        if userform.is_valid():
            origin_form = userform.cleaned_data["user_file"]
            origin_name = origin_form.name
            original_file = os.path.join(settings.MEDIA_ROOT, origin_name)

            .
            .
            .

            original_name = ImageDoc(imgfile=origin_name)
            original_name.save()

            .
            .
            .

            userform = ImgDocForm()
        else:
            return HttpResponse('Nooo!')

    else:
        userform = ImgDocForm()

    data.update(image_gallery = ImageDoc.objects.only('imgfile'))
    data.update(userform=userform)
    data.update(csrf(request))
    return render(request, 'upload.html', data)

编辑:我相信人们可以显着清理索引文件。此外,那里的底部不是很优雅,但它有效。

还有upload.html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
</head>
<body>

<div>

    <form method="post" action="" enctype="multipart/form-data">
        {% csrf_token %}
        {{ userform.as_p }}
        <input type="submit">
    </form>

    <br><br>

    <h2>{{ origin_name }} (original)</h2>

    {% if origin_name %}
        <img src="{{ MEDIA_URL }}{{ origin_name }}">
    {% endif %}

    <br><br>
    {% if image_gallery %}
        {% for image in image_gallery %}
            <img src="/{{ image.thumbfile }}">
        {% endfor %}
    {% endif %}    
</div>
</body>
</html>

谢谢!

【问题讨论】:

    标签: django django-models django-forms django-templates django-views


    【解决方案1】:

    您可以在视图中获取当前登录的用户request.user

    【讨论】:

    • 感谢您的回复!所以我应该使用它来获取id,并将其用作pk,对吗?像这样? userform = ImgDocForm(request.POST, request.FILES, pk=request.user.id)
    • @Bob 您是否尝试从上传的文件创建 ImgDoc?您可以将其分配给您的 ImgDoc.user 字段。如果您想将其分配给表单,请参阅stackoverflow.com/questions/18246326/…
    • 感谢@serg 回复!是的,我正在尝试将文件存储到 ImgDoc 中。不幸的是,您链接的示例似乎不起作用,但也许我错误地实现了它?目前我正在尝试使用表单集来完成工作,这是推荐的吗?或者这是错误的做法?我之所以使用那个是因为我之前有一个类似的项目,两个相关的模型,我无法保存到子模型。使用表单集让我可以做到这一点。 .但是,在这种情况下,我没有使用从 URL 捕获的 ID。稍后,我将在下面粘贴我当前的代码供您查看。
    • 感谢@serg 的帮助!我不需要使用表单集或任何复杂的东西。一个基本的文件保存似乎可以解决问题,模型将实例引用为“request.user.id”。我稍后会将上面的解决方案作为上面的编辑发布(如果有人好奇的话)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-30
    • 2015-04-23
    • 2012-10-05
    • 2012-12-19
    • 1970-01-01
    • 2011-12-22
    • 1970-01-01
    相关资源
    最近更新 更多