小编stt*_*ter的帖子

Django的ModelForm unique_together验证

我有一个看起来像这样的Django模型.

class Solution(models.Model):
    '''
    Represents a solution to a specific problem.
    '''
    name = models.CharField(max_length=50)
    problem = models.ForeignKey(Problem)
    description = models.TextField(blank=True)
    date = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ("name", "problem")
Run Code Online (Sandbox Code Playgroud)

我使用表单添加如下所示的模型:

class SolutionForm(forms.ModelForm):
    class Meta:
        model = Solution
        exclude = ['problem']
Run Code Online (Sandbox Code Playgroud)

我的问题是,SolutionForm不验证Solutionunique_together约束,因此,它IntegrityError在尝试保存表单时返回一个.我知道我可以validate_unique用来手动检查这个,但我想知道是否有任何方法可以在表单验证中捕获它并自动返回表单错误.

谢谢.

django validation modelform

57
推荐指数
4
解决办法
2万
查看次数

Django使用测试夹具测试FileField

我正在尝试为一些具有FileField的模型构建测试.该模型如下所示:

class SolutionFile(models.Model):
    '''
    A file from a solution.
    '''
    solution = models.ForeignKey(Solution)
    file = models.FileField(upload_to=make_solution_file_path)
Run Code Online (Sandbox Code Playgroud)

我遇到了两个问题:

  1. 使用时将数据保存到夹具时./manage.py dumpdata,不保存文件内容,只将文件名保存到夹具中.虽然我发现这是预期的行为,因为文件内容没有保存到数据库中,我想以某种方式将这些信息包含在夹具中进行测试.

  2. 我有一个用于上传文件的测试用例,如下所示:

    def test_post_solution_file(self):
        import tempfile
        import os
        filename = tempfile.mkstemp()[1]
        f = open(filename, 'w')
        f.write('These are the file contents')
        f.close()
        f = open(filename, 'r')
        post_data = {'file': f}
        response = self.client.post(self.solution.get_absolute_url()+'add_solution_file/', post_data,
                                    follow=True)
        f.close()
        os.remove(filename)
        self.assertTemplateUsed(response, 'tests/solution_detail.html')
        self.assertContains(response, os.path.basename(filename))
    
    Run Code Online (Sandbox Code Playgroud)

虽然此测试工作正常,但在完成后将上传的文件保留在媒体目录中.当然,删除可以照顾tearDown(),但我想知道Django是否有另一种处理方式.

我想到的一个解决方案是使用不同的媒体文件夹进行测试,必须与测试夹具保持同步.有没有办法在settings.py运行测试时指定另一个媒体目录?我可以在dumpdata中包含某种钩子,以便同步媒体文件夹中的文件吗?

那么,是否有更多的Pythonic或Django特定方式处理涉及文件的单元测试?

python django unit-testing django-testing filefield

24
推荐指数
2
解决办法
5092
查看次数

检测GridView滚动速度 - Android

我有一个自定义的GridView子视图,我用它来显示一些自定义的3D动画/效果.我这样做的方法是重写dispatchDraw().

理想情况下,我想知道绘制时滚动的当前速度.目前,我使用GestureDetector.OnGestureListener和捕获onScroll事件,这非常有效,除了它不会将flings检测为滚动事件.

我想到的一个想法是捕获onFling事件,然后自己进行未来的处理,以便在以后检测速度.

有没有更好的方法来实现这一目标?有什么简单的方法可以查询GridView的当前滚动速度吗?

谢谢.

android

10
推荐指数
1
解决办法
2181
查看次数

维持Django分叉的南迁移

我正在研究一个非常复杂的Django项目(50多个模型),它有一些复杂的逻辑(许多不同的工作流程,视图,信号,API,后台任务等).我们称之为project-base.目前正在使用Django 1.6 + South迁移和其他一些第三方应用程序.

现在,其中一个要求是创建一个这个项目的分支,它将在这里和那里添加一些字段/模型以及一些额外的逻辑.我们称之为project-fork.大多数额外的工作将在现有模型之上,但也会有一些新的.

随着project-base未来的发展,我们希望这些功能也能进入project-fork(就像git-land中的rebase/merge).额外的更改project-fork将不会合并回来project-base.

有什么可能是实现这一目标的最佳方式?以下是我的一些想法:

  1. 使用南合并在project-fork保持它最新的与最新变化project-base,为解释在这里.使用信号和任何其他必要手段来保持新逻辑project-fork尽可能松散耦合,以避免任何潜在的冲突.

  2. 不要修改任何原始project-base模型,而是在引用旧模型的不同应用程序中创建新模型(即使用OneToOneField).额外的逻辑可能会在旧的和/或新的应用程序中结束.

  3. 你的想法请:)

我会选择选项1,因为它看起来整体上并不复杂,但可能会带来更大的风险.以下是我将如何看待它:

迁移project-base:

  • 0001_project_base_one
  • 0002_project_base_two
  • 0003_project_base_three

迁移project-fork:

  • 0001_project_base_one
  • 0002_project_fork_one

合并后,迁移将如下所示:

  • 0001_project_base_one
  • 0002_project_base_two
  • 0002_project_fork_one
  • 0003_project_base_three
  • 0004_project_fork_merge_noop (添加到两个项目的更改中合并)

使用这种方法有任何陷阱吗?有没有更好的办法?

感谢您的时间.

django merge rebase django-models django-south

10
推荐指数
1
解决办法
157
查看次数

来自信号处理程序的longjmp()

我正在使用以下代码尝试从用户读取输入并超时并在超过5秒后退出.这是通过setjmp/longjmp和SIGALRM信号的组合来实现的.

这是代码:

#include <stdio.h>
#include <setjmp.h>
#include <unistd.h>
#include <string.h>
#include <sys/signal.h>

jmp_buf buffer;

// this will cause t_gets() to return -2
void timeout() {
    longjmp(buffer, 1);
}

int t_gets(char* s, int t)
{
    char* ret;
    signal(SIGALRM, timeout);
    if (setjmp(buffer) != 0)
        return -2; // <--- timeout() will jump here
    alarm(t);
    // if fgets() does not return in t seconds, SIGALARM handler timeout()
    // will be called, causing t_gets() to return -2
    ret = fgets(s, 100, stdin);
    alarm(0);
    if (ret …
Run Code Online (Sandbox Code Playgroud)

c unix signals longjmp

5
推荐指数
1
解决办法
5146
查看次数