标签归档:Django

Django:使用形式在一个模板中的多个模型

问题:Django:使用形式在一个模板中的多个模型

我正在构建一个支持票证跟踪应用程序,并希望从一个页面创建一些模型。票证通过ForeignKey属于客户。注释也通过ForeignKey属于票证。我想选择一个客户(这是一个单独的项目)或创建一个新客户,然后创建一个工单,最后创建一个分配给新工单的便笺。

由于我是Django的新手,因此我倾向于反复工作,每次尝试新功能。我玩过ModelForms,但是我想隐藏一些字段并进行一些复杂的验证。似乎我正在寻找的控制级别需要表单集或手动完成所有操作,并完成一个繁琐的手工编码模板页面,而我试图避免这种情况。

我缺少一些可爱的功能吗?有人对使用表单集有很好的参考或示例吗?我花了整个周末为他们准备API文档,但我仍然一无所知。如果我分解并手工编码所有内容,这是设计问题吗?

I’m building a support ticket tracking app and have a few models I’d like to create from one page. Tickets belong to a Customer via a ForeignKey. Notes belong to Tickets via a ForeignKey as well. I’d like to have the option of selecting a Customer (that’s a whole separate project) OR creating a new Customer, then creating a Ticket and finally creating a Note assigned to the new ticket.

Since I’m fairly new to Django, I tend to work iteratively, trying out new features each time. I’ve played with ModelForms but I want to hide some of the fields and do some complex validation. It seems like the level of control I’m looking for either requires formsets or doing everything by hand, complete with a tedious, hand-coded template page, which I’m trying to avoid.

Is there some lovely feature I’m missing? Does someone have a good reference or example for using formsets? I spent a whole weekend on the API docs for them and I’m still clueless. Is it a design issue if I break down and hand-code everything?


回答 0

使用ModelForms实在不是太难。假设您有A,B和C表单。您打印出每个表单和页面,现在需要处理POST。

if request.POST():
    a_valid = formA.is_valid()
    b_valid = formB.is_valid()
    c_valid = formC.is_valid()
    # we do this since 'and' short circuits and we want to check to whole page for form errors
    if a_valid and b_valid and c_valid:
        a = formA.save()
        b = formB.save(commit=False)
        c = formC.save(commit=False)
        b.foreignkeytoA = a
        b.save()
        c.foreignkeytoB = b
        c.save()

是用于自定义验证的文档。

This really isn’t too hard to implement with ModelForms. So lets say you have Forms A, B, and C. You print out each of the forms and the page and now you need to handle the POST.

if request.POST():
    a_valid = formA.is_valid()
    b_valid = formB.is_valid()
    c_valid = formC.is_valid()
    # we do this since 'and' short circuits and we want to check to whole page for form errors
    if a_valid and b_valid and c_valid:
        a = formA.save()
        b = formB.save(commit=False)
        c = formC.save(commit=False)
        b.foreignkeytoA = a
        b.save()
        c.foreignkeytoB = b
        c.save()

Here are the docs for custom validation.


回答 1

我一天前也处于相同的情况,这是我的2美分:

1)我可以在这里找到单一形式的多个模型输入的最短,最简洁的演示:http : //collingrady.wordpress.com/2008/02/18/editing-multiple-objects-in-django-with-newforms/

简而言之:为每个模型创建一个表单<form>,使用prefixkeyarg 将它们都提交到模板中,并进行视图句柄验证。如果存在依赖关系,只需确保在依赖关系之前保存“父”模型,并在提交“子”模型的保存之前使用父代的ID作为外键。链接中有演示。

2)也许表单集可打成了这样做,但据我的钻研,表单集主要用于输入相同的模型,它的倍数可能 /模型由外键可以任意捆绑到另一种模式。但是,似乎没有默认选项可输入多个模型的数据,而这并不是表单集的含义。

I just was in about the same situation a day ago, and here are my 2 cents:

1) I found arguably the shortest and most concise demonstration of multiple model entry in single form here: http://collingrady.wordpress.com/2008/02/18/editing-multiple-objects-in-django-with-newforms/ .

In a nutshell: Make a form for each model, submit them both to template in a single <form>, using prefix keyarg and have the view handle validation. If there is dependency, just make sure you save the “parent” model before dependant, and use parent’s ID for foreign key before commiting save of “child” model. The link has the demo.

2) Maybe formsets can be beaten into doing this, but as far as I delved in, formsets are primarily for entering multiples of the same model, which may be optionally tied to another model/models by foreign keys. However, there seem to be no default option for entering more than one model’s data and that’s not what formset seems to be meant for.


回答 2

我最近遇到了一些问题,只是想出了解决方法。假设您有三个类,Primary,B,C,并且B,C具有Primary的外键

    class PrimaryForm(ModelForm):
        class Meta:
            model = Primary

    class BForm(ModelForm):
        class Meta:
            model = B
            exclude = ('primary',)

    class CForm(ModelForm):
         class Meta:
            model = C
            exclude = ('primary',)

    def generateView(request):
        if request.method == 'POST': # If the form has been submitted...
            primary_form = PrimaryForm(request.POST, prefix = "primary")
            b_form = BForm(request.POST, prefix = "b")
            c_form = CForm(request.POST, prefix = "c")
            if primary_form.is_valid() and b_form.is_valid() and c_form.is_valid(): # All validation rules pass
                    print "all validation passed"
                    primary = primary_form.save()
                    b_form.cleaned_data["primary"] = primary
                    b = b_form.save()
                    c_form.cleaned_data["primary"] = primary
                    c = c_form.save()
                    return HttpResponseRedirect("/viewer/%s/" % (primary.name))
            else:
                    print "failed"

        else:
            primary_form = PrimaryForm(prefix = "primary")
            b_form = BForm(prefix = "b")
            c_form = Form(prefix = "c")
     return render_to_response('multi_model.html', {
     'primary_form': primary_form,
     'b_form': b_form,
     'c_form': c_form,
      })

此方法应允许您执行所需的任何验证,以及在同一页面上生成所有三个对象。我还使用了JavaScript和隐藏字段来允许在同一页面上生成多个B,C对象。

I very recently had the some problem and just figured out how to do this. Assuming you have three classes, Primary, B, C and that B,C have a foreign key to primary

    class PrimaryForm(ModelForm):
        class Meta:
            model = Primary

    class BForm(ModelForm):
        class Meta:
            model = B
            exclude = ('primary',)

    class CForm(ModelForm):
         class Meta:
            model = C
            exclude = ('primary',)

    def generateView(request):
        if request.method == 'POST': # If the form has been submitted...
            primary_form = PrimaryForm(request.POST, prefix = "primary")
            b_form = BForm(request.POST, prefix = "b")
            c_form = CForm(request.POST, prefix = "c")
            if primary_form.is_valid() and b_form.is_valid() and c_form.is_valid(): # All validation rules pass
                    print "all validation passed"
                    primary = primary_form.save()
                    b_form.cleaned_data["primary"] = primary
                    b = b_form.save()
                    c_form.cleaned_data["primary"] = primary
                    c = c_form.save()
                    return HttpResponseRedirect("/viewer/%s/" % (primary.name))
            else:
                    print "failed"

        else:
            primary_form = PrimaryForm(prefix = "primary")
            b_form = BForm(prefix = "b")
            c_form = Form(prefix = "c")
     return render_to_response('multi_model.html', {
     'primary_form': primary_form,
     'b_form': b_form,
     'c_form': c_form,
      })

This method should allow you to do whatever validation you require, as well as generating all three objects on the same page. I have also used javascript and hidden fields to allow the generation of multiple B,C objects on the same page.


回答 3

来自的MultiModelFormdjango-betterforms是一个方便的包装程序,可以执行Gnudiff的答案中所述。它将regulars包装ModelForm在单个类中,该类透明(至少对于基本用法而言)用作单个形式。我从下面的文档中复制了一个示例。

# forms.py
from django import forms
from django.contrib.auth import get_user_model
from betterforms.multiform import MultiModelForm
from .models import UserProfile

User = get_user_model()

class UserEditForm(forms.ModelForm):
    class Meta:
        fields = ('email',)

class UserProfileForm(forms.ModelForm):
    class Meta:
        fields = ('favorite_color',)

class UserEditMultiForm(MultiModelForm):
    form_classes = {
        'user': UserEditForm,
        'profile': UserProfileForm,
    }

# views.py
from django.views.generic import UpdateView
from django.core.urlresolvers import reverse_lazy
from django.shortcuts import redirect
from django.contrib.auth import get_user_model
from .forms import UserEditMultiForm

User = get_user_model()

class UserSignupView(UpdateView):
    model = User
    form_class = UserEditMultiForm
    success_url = reverse_lazy('home')

    def get_form_kwargs(self):
        kwargs = super(UserSignupView, self).get_form_kwargs()
        kwargs.update(instance={
            'user': self.object,
            'profile': self.object.profile,
        })
        return kwargs

The MultiModelForm from django-betterforms is a convenient wrapper to do what is described in Gnudiff’s answer. It wraps regular ModelForms in a single class which is transparently (at least for basic usage) used as a single form. I’ve copied an example from their docs below.

# forms.py
from django import forms
from django.contrib.auth import get_user_model
from betterforms.multiform import MultiModelForm
from .models import UserProfile

User = get_user_model()

class UserEditForm(forms.ModelForm):
    class Meta:
        fields = ('email',)

class UserProfileForm(forms.ModelForm):
    class Meta:
        fields = ('favorite_color',)

class UserEditMultiForm(MultiModelForm):
    form_classes = {
        'user': UserEditForm,
        'profile': UserProfileForm,
    }

# views.py
from django.views.generic import UpdateView
from django.core.urlresolvers import reverse_lazy
from django.shortcuts import redirect
from django.contrib.auth import get_user_model
from .forms import UserEditMultiForm

User = get_user_model()

class UserSignupView(UpdateView):
    model = User
    form_class = UserEditMultiForm
    success_url = reverse_lazy('home')

    def get_form_kwargs(self):
        kwargs = super(UserSignupView, self).get_form_kwargs()
        kwargs.update(instance={
            'user': self.object,
            'profile': self.object.profile,
        })
        return kwargs

回答 4

我目前有一个解决方法功能(它通过了我的单元测试)。当您只想从其他模型中添加有限数量的字段时,这是一个很好的解决方案。

我在这里想念什么吗?

class UserProfileForm(ModelForm):
    def __init__(self, instance=None, *args, **kwargs):
        # Add these fields from the user object
        _fields = ('first_name', 'last_name', 'email',)
        # Retrieve initial (current) data from the user object
        _initial = model_to_dict(instance.user, _fields) if instance is not None else {}
        # Pass the initial data to the base
        super(UserProfileForm, self).__init__(initial=_initial, instance=instance, *args, **kwargs)
        # Retrieve the fields from the user model and update the fields with it
        self.fields.update(fields_for_model(User, _fields))

    class Meta:
        model = UserProfile
        exclude = ('user',)

    def save(self, *args, **kwargs):
        u = self.instance.user
        u.first_name = self.cleaned_data['first_name']
        u.last_name = self.cleaned_data['last_name']
        u.email = self.cleaned_data['email']
        u.save()
        profile = super(UserProfileForm, self).save(*args,**kwargs)
        return profile

I currently have a workaround functional (it passes my unit tests). It is a good solution to my opinion when you only want to add a limited number of fields from other models.

Am I missing something here ?

class UserProfileForm(ModelForm):
    def __init__(self, instance=None, *args, **kwargs):
        # Add these fields from the user object
        _fields = ('first_name', 'last_name', 'email',)
        # Retrieve initial (current) data from the user object
        _initial = model_to_dict(instance.user, _fields) if instance is not None else {}
        # Pass the initial data to the base
        super(UserProfileForm, self).__init__(initial=_initial, instance=instance, *args, **kwargs)
        # Retrieve the fields from the user model and update the fields with it
        self.fields.update(fields_for_model(User, _fields))

    class Meta:
        model = UserProfile
        exclude = ('user',)

    def save(self, *args, **kwargs):
        u = self.instance.user
        u.first_name = self.cleaned_data['first_name']
        u.last_name = self.cleaned_data['last_name']
        u.email = self.cleaned_data['email']
        u.save()
        profile = super(UserProfileForm, self).save(*args,**kwargs)
        return profile

回答 5

“我想隐藏一些字段并进行一些复杂的验证。”

我从内置的管理界面开始。

  1. 构建ModelForm以显示所需的字段。

  2. 用表单中的验证规则扩展表单。通常这是一种clean方法。

    确保这部分工作正常。

完成此操作后,您可以离开内置的管理界面。

然后,您可以在单个网页上四处查找与部分相关的表单。这是一堆模板材料,可在一个页面上显示所有表单。

然后,您必须编写视图函数来读取和验证各种表单内容,并执行各种对象saves()。

“如果我分解并手动编码所有内容,这是设计问题吗?” 不,只是很多时间而没有太多好处。

“I want to hide some of the fields and do some complex validation.”

I start with the built-in admin interface.

  1. Build the ModelForm to show the desired fields.

  2. Extend the Form with the validation rules within the form. Usually this is a clean method.

    Be sure this part works reasonably well.

Once this is done, you can move away from the built-in admin interface.

Then you can fool around with multiple, partially related forms on a single web page. This is a bunch of template stuff to present all the forms on a single page.

Then you have to write the view function to read and validated the various form things and do the various object saves().

“Is it a design issue if I break down and hand-code everything?” No, it’s just a lot of time for not much benefit.


回答 6

根据Django文档,内联表单集用于此目的:“内联表单集是模型表单集之上的一个小抽象层。它们简化了通过外键处理相关对象的情况”。

参见https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#inline-formsets

According to Django documentation, inline formsets are for this purpose: “Inline formsets is a small abstraction layer on top of model formsets. These simplify the case of working with related objects via a foreign key”.

See https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#inline-formsets


更改源代码时自动加载gunicorn

问题:更改源代码时自动加载gunicorn

最后,我将开发环境从runserver迁移到gunicorn / nginx。

将runserver的自动重载功能复制到gunicorn会很方便,因此当源更改时,服务器会自动重新启动。否则,我必须使用手动重新启动服务器kill -HUP

有什么方法可以避免手动重启?

Finally I migrated my development env from runserver to gunicorn/nginx.

It’d be convenient to replicate the autoreload feature of runserver to gunicorn, so the server automatically restarts when source changes. Otherwise I have to restart the server manually with kill -HUP.

Any way to avoid the manual restart?


回答 0

尽管这是个老问题,但仅出于一致性考虑-因为19.0版本的gunicorn可以--reload选择。因此,不再需要第三方工具。

While this is old question you need to know that ever since version 19.0 gunicorn has had the --reload option. So now no third party tools are needed.


回答 1

一种选择是使用–max-requests通过添加--max-requests 1到启动选项来将每个生成的进程限制为仅服务一个请求。每个新产生的进程都应该看到您的代码更改,并且在开发环境中,每个请求的额外启动时间可以忽略不计。

One option would be to use the –max-requests to limit each spawned process to serving only one request by adding --max-requests 1 to the startup options. Every newly spawned process should see your code changes and in a development environment the extra startup time per request should be negligible.


回答 2

Bryan Helmig提出了这个建议,我对其进行了修改,以使其直接使用run_gunicorn而不是gunicorn直接启动,以便可以将这3个命令剪切并粘贴到django项目根文件夹中的shell中(激活了virtualenv):

pip install watchdog -U
watchmedo shell-command --patterns="*.py;*.html;*.css;*.js" --recursive --command='echo "${watch_src_path}" && kill -HUP `cat gunicorn.pid`' . &
python manage.py run_gunicorn 127.0.0.1:80 --pid=gunicorn.pid

Bryan Helmig came up with this and I modified it to use run_gunicorn instead of launching gunicorn directly, to make it possible to just cut and paste these 3 commands into a shell in your django project root folder (with your virtualenv activated):

pip install watchdog -U
watchmedo shell-command --patterns="*.py;*.html;*.css;*.js" --recursive --command='echo "${watch_src_path}" && kill -HUP `cat gunicorn.pid`' . &
python manage.py run_gunicorn 127.0.0.1:80 --pid=gunicorn.pid

回答 3

我使用git push部署到生产环境,并设置git挂钩来运行脚本。这种方法的优点是您还可以同时进行迁移和软件包安装。 https://mikeeverhart.net/2013/01/using-git-to-deploy-code/

mkdir -p /home/git/project_name.git
cd /home/git/project_name.git
git init --bare

然后创建一个脚本/home/git/project_name.git/hooks/post-receive

#!/bin/bash
GIT_WORK_TREE=/path/to/project git checkout -f
source /path/to/virtualenv/activate
pip install -r /path/to/project/requirements.txt
python /path/to/project/manage.py migrate
sudo supervisorctl restart project_name

确保为chmod u+x post-receive,并将用户添加到sudoers。允许它sudo supervisorctl不带密码运行。 https://www.cyberciti.biz/faq/linux-unix-running-sudo-command-without-a-password/

在本地/开发服务器上,我进行了设置,git remote从而可以推送到生产服务器

git remote add production ssh://user_name@production-server/home/git/project_name.git

# initial push
git push production +master:refs/heads/master

# subsequent push
git push production master

另外,在脚本运行时,您将看到所有提示。因此,您将看到迁移/软件包安装/主管重启是否存在任何问题。

I use git push to deploy to production and set up git hooks to run a script. The advantage of this approach is you can also do your migration and package installation at the same time. https://mikeeverhart.net/2013/01/using-git-to-deploy-code/

mkdir -p /home/git/project_name.git
cd /home/git/project_name.git
git init --bare

Then create a script /home/git/project_name.git/hooks/post-receive.

#!/bin/bash
GIT_WORK_TREE=/path/to/project git checkout -f
source /path/to/virtualenv/activate
pip install -r /path/to/project/requirements.txt
python /path/to/project/manage.py migrate
sudo supervisorctl restart project_name

Make sure to chmod u+x post-receive, and add user to sudoers. Allow it to run sudo supervisorctl without password. https://www.cyberciti.biz/faq/linux-unix-running-sudo-command-without-a-password/

From my local / development server, I set up git remote that allows me to push to the production server

git remote add production ssh://user_name@production-server/home/git/project_name.git

# initial push
git push production +master:refs/heads/master

# subsequent push
git push production master

As a bonus, you will get to see all the prompts as the script is running. So you will see if there is any issue with the migration/package installation/supervisor restart.


如何使用Django删除表中的所有数据

问题:如何使用Django删除表中的所有数据

我有两个问题:

  1. 如何在Django中删除表格?
  2. 如何删除表格中的所有数据?

这是我的代码,不成功:

Reporter.objects.delete()

I have two questions:

  1. How do I delete a table in Django?
  2. How do I remove all the data in the table?

This is my code, which is not successful:

Reporter.objects.delete()

回答 0

经理内部:

def delete_everything(self):
    Reporter.objects.all().delete()

def drop_table(self):
    cursor = connection.cursor()
    table_name = self.model._meta.db_table
    sql = "DROP TABLE %s;" % (table_name, )
    cursor.execute(sql)

Inside a manager:

def delete_everything(self):
    Reporter.objects.all().delete()

def drop_table(self):
    cursor = connection.cursor()
    table_name = self.model._meta.db_table
    sql = "DROP TABLE %s;" % (table_name, )
    cursor.execute(sql)

回答 1

根据最新文档,正确的调用方法是:

Reporter.objects.all().delete()

As per the latest documentation, the correct method to call would be:

Reporter.objects.all().delete()

回答 2

如果要从所有表中删除所有数据,则可能需要尝试使用命令python manage.py flush。这将删除表中的所有数据,但表本身仍将存在。

在此处查看更多信息:https : //docs.djangoproject.com/en/1.8/ref/django-admin/

If you want to remove all the data from all your tables, you might want to try the command python manage.py flush. This will delete all of the data in your tables, but the tables themselves will still exist.

See more here: https://docs.djangoproject.com/en/1.8/ref/django-admin/


回答 3

使用外壳,

1)删除表:

python manage.py dbshell
>> DROP TABLE {app_name}_{model_name}

2)要从表中删除所有数据:

python manage.py shell
>> from {app_name}.models import {model_name}
>> {model_name}.objects.all().delete()

Using shell,

1) For Deleting the table:

python manage.py dbshell
>> DROP TABLE {app_name}_{model_name}

2) For removing all data from table:

python manage.py shell
>> from {app_name}.models import {model_name}
>> {model_name}.objects.all().delete()

回答 4

Django 1.11从数据库表中删除所有对象-

Entry.objects.all().delete()  ## Entry being Model Name. 

请参考以下引用的Django官方文档-https: //docs.djangoproject.com/en/1.11/topics/db/queries/#deleting-objects

请注意,delete()是唯一未在Manager本身上公开的QuerySet方法。这是一种安全机制,可防止您意外地请求Entry.objects.delete()并删除所有条目。如果确实要删除所有对象,则必须显式请求一个完整的查询集:

我自己尝试了以下代码片段, somefilename.py

    # for deleting model objects
    from django.db import connection
    def del_model_4(self):
        with connection.schema_editor() as schema_editor:
            schema_editor.delete_model(model_4)

在我内部,我views.py有一个视图,只显示一个html页面…

  def data_del_4(request):
      obj = calc_2() ## 
      obj.del_model_4()
      return render(request, 'dc_dash/data_del_4.html') ## 

它结束了从-model == model_4删除所有条目的操作,但是当我尝试确定model_4的所有对象都已删除时,我现在看到管理控制台中的错误屏幕…

ProgrammingError at /admin/dc_dash/model_4/
relation "dc_dash_model_4" does not exist
LINE 1: SELECT COUNT(*) AS "__count" FROM "dc_dash_model_4" 

请考虑一下-如果我们不转到ADMIN控制台并尝试查看模型的对象-已经被删除-Django应用程序将按预期工作。

django管理员截屏

Django 1.11 delete all objects from a database table –

Entry.objects.all().delete()  ## Entry being Model Name. 

Refer the Official Django documentation here as quoted below – https://docs.djangoproject.com/en/1.11/topics/db/queries/#deleting-objects

Note that delete() is the only QuerySet method that is not exposed on a Manager itself. This is a safety mechanism to prevent you from accidentally requesting Entry.objects.delete(), and deleting all the entries. If you do want to delete all the objects, then you have to explicitly request a complete query set:

I myself tried the code snippet seen below within my somefilename.py

    # for deleting model objects
    from django.db import connection
    def del_model_4(self):
        with connection.schema_editor() as schema_editor:
            schema_editor.delete_model(model_4)

and within my views.py i have a view that simply renders a html page …

  def data_del_4(request):
      obj = calc_2() ## 
      obj.del_model_4()
      return render(request, 'dc_dash/data_del_4.html') ## 

it ended deleting all entries from – model == model_4 , but now i get to see a Error screen within Admin console when i try to asceratin that all objects of model_4 have been deleted …

ProgrammingError at /admin/dc_dash/model_4/
relation "dc_dash_model_4" does not exist
LINE 1: SELECT COUNT(*) AS "__count" FROM "dc_dash_model_4" 

Do consider that – if we do not go to the ADMIN Console and try and see objects of the model – which have been already deleted – the Django app works just as intended.

django admin screencapture


回答 5

有两种方法:

要直接删除它:

SomeModel.objects.filter(id=id).delete()

要从实例中删除它:

instance1 = SomeModel.objects.get(id=id)
instance1.delete()

//不要使用相同的名称

There are a couple of ways:

To delete it directly:

SomeModel.objects.filter(id=id).delete()

To delete it from an instance:

instance1 = SomeModel.objects.get(id=id)
instance1.delete()

// don’t use same name


Django:外键冲突的反向访问器

问题:Django:外键冲突的反向访问器

我有两个从基类继承的Django模型:

- Request
    - Inquiry
    - Analysis

请求具有两个内置用户模型的外键。

create_user = models.ForeignKey(User, related_name='requests_created')
assign_user = models.ForeignKey(User, related_name='requests_assigned')

由于某种原因,我遇到了错误

Reverse accessor for 'Analysis.assign_user' clashes with reverse accessor for 'Inquiry.assign_user'.

我读过的所有内容都说设置related_name应当可以防止冲突,但是我仍然遇到相同的错误。谁能想到为什么会这样?谢谢!

I have two Django models which inherit from a base class:

- Request
    - Inquiry
    - Analysis

Request has two foreign keys to the built-in User model.

create_user = models.ForeignKey(User, related_name='requests_created')
assign_user = models.ForeignKey(User, related_name='requests_assigned')

For some reason I’m getting the error

Reverse accessor for 'Analysis.assign_user' clashes with reverse accessor for 'Inquiry.assign_user'.

Everything I’ve read says that setting the related_name should prevent the clash, but I’m still getting the same error. Can anyone think of why this would be happening? Thanks!


回答 0

这样related_name可以确保各个字段之间不会发生冲突,但是您有两个模型,每个模型都具有这两个字段。您需要在每个模型中放置具体模型的名称,您可以使用一些特殊的字符串替换来做到这一点:

 create_user = models.ForeignKey(User, related_name='%(class)s_requests_created')

The related_name would ensure that the fields were not conflicting with each other, but you have two models, each of which has both of those fields. You need to put the name of the concrete model in each one, which you can do with some special string substitution:

 create_user = models.ForeignKey(User, related_name='%(class)s_requests_created')

如何配置Django以进行简单的开发和部署?

问题:如何配置Django以进行简单的开发和部署?

在进行Django 开发时,我倾向于使用SQLite,但是在实时服务器上,通常需要更强大的功能(例如MySQL / PostgreSQL)。同样,对Django设置也有其他更改:不同的日志记录位置/强度,媒体路径等。

您如何管理所有这些更改,以使部署变得简单,自动化?

I tend to use SQLite when doing Django development, but on a live server something more robust is often needed (MySQL/PostgreSQL, for example). Invariably, there are other changes to make to the Django settings as well: different logging locations / intensities, media paths, etc.

How do you manage all these changes to make deployment a simple, automated process?


回答 0

更新: django-configurations已发布,对于大多数人来说,它可能比手动执行更好。

如果您希望手动进行操作,则我先前的答案仍然适用:

我有多个设置文件。

  • settings_local.py -特定于主机的配置,例如数据库名称,文件路径等。
  • settings_development.py-用于开发的配置,例如DEBUG = True
  • settings_production.py-用于生产的配置,例如SERVER_EMAIL

我将所有这些与一个settings.py首先导入的文件捆绑在一起settings_local.py,然后再将另外两个文件之一捆绑在一起。它决定它通过两个设置加载内settings_local.pyDEVELOPMENT_HOSTSPRODUCTION_HOSTSsettings.py来电platform.node()以查找正在其上运行的计算机的主机名,然后在列表中查找该主机名,并根据在其中找到该主机名的列表加载第二个设置文件。

这样,您真正需要担心的唯一事情就是使settings_local.py文件与主机特定的配置保持最新,并且其他所有内容都会自动处理。

在此处查看示例。

Update: django-configurations has been released which is probably a better option for most people than doing it manually.

If you would prefer to do things manually, my earlier answer still applies:

I have multiple settings files.

  • settings_local.py – host-specific configuration, such as database name, file paths, etc.
  • settings_development.py – configuration used for development, e.g. DEBUG = True.
  • settings_production.py – configuration used for production, e.g. SERVER_EMAIL.

I tie these all together with a settings.py file that firstly imports settings_local.py, and then one of the other two. It decides which to load by two settings inside settings_local.pyDEVELOPMENT_HOSTS and PRODUCTION_HOSTS. settings.py calls platform.node() to find the hostname of the machine it is running on, and then looks for that hostname in the lists, and loads the second settings file depending on which list it finds the hostname in.

That way, the only thing you really need to worry about is keeping the settings_local.py file up to date with the host-specific configuration, and everything else is handled automatically.

Check out an example here.


回答 1

就个人而言,我为该项目使用一个settings.py,我只是让它查找所在的主机名(我的开发机器的主机名以“ gabriel”开头,所以我只有这样:

import socket
if socket.gethostname().startswith('gabriel'):
    LIVEHOST = False
else: 
    LIVEHOST = True

然后在其他地方,我有类似的东西:

if LIVEHOST:
    DEBUG = False
    PREPEND_WWW = True
    MEDIA_URL = 'http://static1.grsites.com/'
else:
    DEBUG = True
    PREPEND_WWW = False
    MEDIA_URL = 'http://localhost:8000/static/'

等等。可读性稍差,但是它可以正常工作,并且省去了处理多个设置文件的麻烦。

Personally, I use a single settings.py for the project, I just have it look up the hostname it’s on (my development machines have hostnames that start with “gabriel” so I just have this:

import socket
if socket.gethostname().startswith('gabriel'):
    LIVEHOST = False
else: 
    LIVEHOST = True

then in other parts I have things like:

if LIVEHOST:
    DEBUG = False
    PREPEND_WWW = True
    MEDIA_URL = 'http://static1.grsites.com/'
else:
    DEBUG = True
    PREPEND_WWW = False
    MEDIA_URL = 'http://localhost:8000/static/'

and so on. A little bit less readable, but it works fine and saves having to juggle multiple settings files.


回答 2

在settings.py的结尾,我有以下内容:

try:
    from settings_local import *
except ImportError:
    pass

这样,如果我想覆盖默认设置,则只需将settings_local.py放在settings.py旁边。

At the end of settings.py I have the following:

try:
    from settings_local import *
except ImportError:
    pass

This way if I want to override default settings I need to just put settings_local.py right next to settings.py.


回答 3

我有两个文件。settings_base.py其中包含通用/默认设置,并且已签入源代码管理。每个部署都有一个单独的settings.py,从头from settings_base import *开始执行,然后根据需要进行覆盖。

I have two files. settings_base.py which contains common/default settings, and which is checked into source control. Each deployment has a separate settings.py, which executes from settings_base import * at the beginning and then overrides as needed.


回答 4

我发现的最简单的方法是:

1)使用默认的settings.py进行本地开发,以及2)创建一个production-settings.py,开头为:

import os
from settings import *

然后只需覆盖生产中不同的设置:

DEBUG = False
TEMPLATE_DEBUG = DEBUG


DATABASES = {
    'default': {
           ....
    }
}

The most simplistic way I found was:

1) use the default settings.py for local development and 2) create a production-settings.py starting with:

import os
from settings import *

And then just override the settings that differ in production:

DEBUG = False
TEMPLATE_DEBUG = DEBUG


DATABASES = {
    'default': {
           ....
    }
}

回答 5

在某种程度上相关,关于使用多个数据库部署Django本身的问题,您可能需要看一下Djangostack。您可以下载一个完全免费的安装程序,该程序允许您安装Apache,Python,Django等。在安装过程中,我们允许您选择要使用的数据库(MySQL,SQLite,PostgreSQL)。在内部自动进行部署时,我们会广泛使用安装程序(它们可以在无人值守模式下运行)。

Somewhat related, for the issue of deploying Django itself with multiple databases, you may want to take a look at Djangostack. You can download a completely free installer that allows you to install Apache, Python, Django, etc. As part of the installation process we allow you to select which database you want to use (MySQL, SQLite, PostgreSQL). We use the installers extensively when automating deployments internally (they can be run in unattended mode).


回答 6

我的settings.py文件位于外部目录中。这样,就不会将其检入源代码管理或被部署覆盖。我将其与所有默认设置一起放入Django项目下的settings.py文件中:

import sys
import os.path

def _load_settings(path):    
    print "Loading configuration from %s" % (path)
    if os.path.exists(path):
    settings = {}
    # execfile can't modify globals directly, so we will load them manually
    execfile(path, globals(), settings)
    for setting in settings:
        globals()[setting] = settings[setting]

_load_settings("/usr/local/conf/local_settings.py")

注意:如果您不信任local_settings.py,这将非常危险。

I have my settings.py file in an external directory. That way, it doesn’t get checked into source control, or over-written by a deploy. I put this in the settings.py file under my Django project, along with any default settings:

import sys
import os.path

def _load_settings(path):    
    print "Loading configuration from %s" % (path)
    if os.path.exists(path):
    settings = {}
    # execfile can't modify globals directly, so we will load them manually
    execfile(path, globals(), settings)
    for setting in settings:
        globals()[setting] = settings[setting]

_load_settings("/usr/local/conf/local_settings.py")

Note: This is very dangerous if you can’t trust local_settings.py.


回答 7

除了吉姆提到的多个设置文件,我也倾向于地方两个设置成我的顶部settings.py文件BASE_DIRBASE_URL设置的代码和URL到现场的基地的路径,所有其他的设置被修改将自己附加到这些。

BASE_DIR = "/home/sean/myapp/" 例如 MEDIA_ROOT = "%smedia/" % BASEDIR

因此,在移动项目时,我只需要编辑这些设置,而无需搜索整个文件。

我还建议您查看一下能够促进远程部署自动化的fabric和Capistrano(Ruby工具,但是它可以用于部署Django应用程序)。

In addition to the multiple settings files mentioned by Jim, I also tend to place two settings into my settings.py file at the top BASE_DIR and BASE_URL set to the path of the code and the URL to the base of the site, all other settings are modified to append themselves to these.

BASE_DIR = "/home/sean/myapp/" e.g. MEDIA_ROOT = "%smedia/" % BASEDIR

So when moving the project I only have to edit these settings and not search the whole file.

I would also recommend looking at fabric and Capistrano (Ruby tool, but it can be used to deploy Django applications) which facilitate automation of remote deployment.


回答 8

好吧,我使用以下配置:

在settings.py的末尾:

#settings.py
try:
    from locale_settings import *
except ImportError:
    pass

在locale_settings.py中:

#locale_settings.py
class Settings(object):

    def __init__(self):
        import settings
        self.settings = settings

    def __getattr__(self, name):
        return getattr(self.settings, name)

settings = Settings()

INSTALLED_APPS = settings.INSTALLED_APPS + (
    'gunicorn',)

# Delete duplicate settings maybe not needed, but I prefer to do it.
del settings
del Settings

Well, I use this configuration:

At the end of settings.py:

#settings.py
try:
    from locale_settings import *
except ImportError:
    pass

And in locale_settings.py:

#locale_settings.py
class Settings(object):

    def __init__(self):
        import settings
        self.settings = settings

    def __getattr__(self, name):
        return getattr(self.settings, name)

settings = Settings()

INSTALLED_APPS = settings.INSTALLED_APPS + (
    'gunicorn',)

# Delete duplicate settings maybe not needed, but I prefer to do it.
del settings
del Settings

回答 9

这么多复杂的答案!

每个settings.py文件都附带:

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

我使用该目录来设置DEBUG变量,如下所示(用您的开发代码所在的directoy代替):

DEBUG=False
if(BASE_DIR=="/path/to/my/dev/dir"):
    DEBUG = True

然后,每次移动settings.py文件时,DEBUG将为False,这是您的生产环境。

每当您需要与开发环境中不同的设置时,只需使用:

if(DEBUG):
    #Debug setting
else:
    #Release setting

So many complicated answers!

Every settings.py file comes with :

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

I use that directory to set the DEBUG variable like this (reaplace with the directoy where your dev code is):

DEBUG=False
if(BASE_DIR=="/path/to/my/dev/dir"):
    DEBUG = True

Then, every time the settings.py file is moved, DEBUG will be False and it’s your production environment.

Every time you need different settings than the ones in your dev environment just use:

if(DEBUG):
    #Debug setting
else:
    #Release setting

回答 10

我认为这取决于站点的大小,是否需要逐步使用SQLite,我已经在几个较小的实时站点上成功使用了SQLite,并且运行良好。

I think it depends on the size of the site as to whether you need to step up from using SQLite, I’ve successfully used SQLite on several smaller live sites and it runs great.


回答 11

我使用环境:

if os.environ.get('WEB_MODE', None) == 'production' :
   from settings_production import *
else :
   from settings_dev import *

我相信这是一种更好的方法,因为最终您需要针对测试环境进行特殊设置,并且可以轻松地将其添加到此条件中。

I use environment:

if os.environ.get('WEB_MODE', None) == 'production' :
   from settings_production import *
else :
   from settings_dev import *

I believe this is a much better approach, because eventually you need special settings for your test environment, and you can easily add it to this condition.


回答 12

这是一个较旧的文章,但是我认为如果我添加这个有用的内容library,它将简化事情。

使用Django配置

快速开始

pip install django-configurations

然后子类化包含的配置。配置类在项目的settings.py或用于存储设置常量的任何其他模块中,例如:

# mysite/settings.py

from configurations import Configuration

class Dev(Configuration):
    DEBUG = True

DJANGO_CONFIGURATION环境变量设置为您刚刚创建的类的名称,例如~/.bashrc

export DJANGO_CONFIGURATION=Dev

并将DJANGO_SETTINGS_MODULE环境变量照常导入模块导入路径,例如在bash中:

export DJANGO_SETTINGS_MODULE=mysite.settings

另外--configuration在使用Django管理命令时,请按照Django默认--settings命令行选项的方式提供选项,例如:

python manage.py runserver --settings=mysite.settings --configuration=Dev

为了使Django使用您的配置,您现在必须修改您的manage.pywsgi.py脚本,以使用django-configurations的相应启动程序版本,例如,使用django-configurations 的典型manage.py如下所示:

#!/usr/bin/env python

import os
import sys

if __name__ == "__main__":
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
    os.environ.setdefault('DJANGO_CONFIGURATION', 'Dev')

    from configurations.management import execute_from_command_line

    execute_from_command_line(sys.argv)

请注意,在第10行中,我们不使用通用工具django.core.management.execute_from_command_line,而是使用configurations.management.execute_from_command_line

这同样适用于您的wsgi.py文件,例如:

import os

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
os.environ.setdefault('DJANGO_CONFIGURATION', 'Dev')

from configurations.wsgi import get_wsgi_application

application = get_wsgi_application()

这里我们不使用默认django.core.wsgi.get_wsgi_application功能,而是使用configurations.wsgi.get_wsgi_application

而已!现在,您可以将项目与manage.py以及您最喜欢的启用WSGI的服务器一起使用。

This is an older post but I think if I add this useful library it will simplify things.

Use django-configuration

Quickstart

pip install django-configurations

Then subclass the included configurations.Configuration class in your project’s settings.py or any other module you’re using to store the settings constants, e.g.:

# mysite/settings.py

from configurations import Configuration

class Dev(Configuration):
    DEBUG = True

Set the DJANGO_CONFIGURATION environment variable to the name of the class you just created, e.g. in ~/.bashrc:

export DJANGO_CONFIGURATION=Dev

and the DJANGO_SETTINGS_MODULE environment variable to the module import path as usual, e.g. in bash:

export DJANGO_SETTINGS_MODULE=mysite.settings

Alternatively supply the --configuration option when using Django management commands along the lines of Django’s default --settings command line option, e.g.:

python manage.py runserver --settings=mysite.settings --configuration=Dev

To enable Django to use your configuration you now have to modify your manage.py or wsgi.py script to use django-configurations’ versions of the appropriate starter functions, e.g. a typical manage.py using django-configurations would look like this:

#!/usr/bin/env python

import os
import sys

if __name__ == "__main__":
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
    os.environ.setdefault('DJANGO_CONFIGURATION', 'Dev')

    from configurations.management import execute_from_command_line

    execute_from_command_line(sys.argv)

Notice in line 10 we don’t use the common tool django.core.management.execute_from_command_line but instead configurations.management.execute_from_command_line.

The same applies to your wsgi.py file, e.g.:

import os

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
os.environ.setdefault('DJANGO_CONFIGURATION', 'Dev')

from configurations.wsgi import get_wsgi_application

application = get_wsgi_application()

Here we don’t use the default django.core.wsgi.get_wsgi_application function but instead configurations.wsgi.get_wsgi_application.

That’s it! You can now use your project with manage.py and your favorite WSGI enabled server.


回答 13

实际上,您可能应该考虑为您的开发和生产环境使用相同(或几乎相同)的配置。否则,会不时出现“嘿,它可以在我的机器上工作”之类的情况。

因此,为了自动化部署并消除那些WOMM问题,只需使用Docker即可

In fact you should probably consider having the same (or almost the same) configs for your development and production environment. Otherwise, situations like “Hey, it works on my machine” will happen from time to time.

So in order to automate your deployment and eliminate those WOMM issues, just use Docker.


Django URLs TypeError:对于include(),视图必须是可调用的或列表/元组

问题:Django URLs TypeError:对于include(),视图必须是可调用的或列表/元组

升级到Django 1.10后,出现错误:

TypeError: view must be a callable or a list/tuple in the case of include().

我的urls.py如下:

from django.conf.urls import include, url

urlpatterns = [
    url(r'^$', 'myapp.views.home'),
    url(r'^contact/$', 'myapp.views.contact'),
    url(r'^login/$', 'django.contrib.auth.views.login'),
]

完整的回溯是:

Traceback (most recent call last):
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/utils/autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 121, in inner_run
    self.check(display_num_errors=True)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/management/base.py", line 385, in check
    include_deployment_checks=include_deployment_checks,
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/management/base.py", line 372, in _run_checks
    return checks.run_checks(**kwargs)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/checks/registry.py", line 81, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/checks/urls.py", line 14, in check_url_config
    return check_resolver(resolver)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/checks/urls.py", line 24, in check_resolver
    for pattern in resolver.url_patterns:
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/urls/resolvers.py", line 310, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/urls/resolvers.py", line 303, in urlconf_module
    return import_module(self.urlconf_name)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/Users/alasdair/dev/urlproject/urlproject/urls.py", line 28, in <module>
    url(r'^$', 'myapp.views.home'),
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/conf/urls/__init__.py", line 85, in url
    raise TypeError('view must be a callable or a list/tuple in the case of include().')
TypeError: view must be a callable or a list/tuple in the case of include().

After upgrading to Django 1.10, I get the error:

TypeError: view must be a callable or a list/tuple in the case of include().

My urls.py is as follows:

from django.conf.urls import include, url

urlpatterns = [
    url(r'^$', 'myapp.views.home'),
    url(r'^contact/$', 'myapp.views.contact'),
    url(r'^login/$', 'django.contrib.auth.views.login'),
]

The full traceback is:

Traceback (most recent call last):
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/utils/autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 121, in inner_run
    self.check(display_num_errors=True)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/management/base.py", line 385, in check
    include_deployment_checks=include_deployment_checks,
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/management/base.py", line 372, in _run_checks
    return checks.run_checks(**kwargs)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/checks/registry.py", line 81, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/checks/urls.py", line 14, in check_url_config
    return check_resolver(resolver)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/checks/urls.py", line 24, in check_resolver
    for pattern in resolver.url_patterns:
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/urls/resolvers.py", line 310, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/urls/resolvers.py", line 303, in urlconf_module
    return import_module(self.urlconf_name)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/Users/alasdair/dev/urlproject/urlproject/urls.py", line 28, in <module>
    url(r'^$', 'myapp.views.home'),
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/conf/urls/__init__.py", line 85, in url
    raise TypeError('view must be a callable or a list/tuple in the case of include().')
TypeError: view must be a callable or a list/tuple in the case of include().

回答 0

Django 1.10不再允许您'myapp.views.home'在URL模式中将视图指定为字符串(例如)。

解决方案是更新您urls.py的视图以包含可调用的视图。这意味着您必须在中导入视图urls.py。如果您的URL模式没有名称,那么现在是添加名称的好时机,因为用虚线python路径进行反向操作不再起作用。

from django.conf.urls import include, url

from django.contrib.auth.views import login
from myapp.views import home, contact

urlpatterns = [
    url(r'^$', home, name='home'),
    url(r'^contact/$', contact, name='contact'),
    url(r'^login/$', login, name='login'),
]

如果有很多视图,则不方便分别导入它们。一种替代方法是从您的应用程序导入视图模块。

from django.conf.urls import include, url

from django.contrib.auth import views as auth_views
from myapp import views as myapp_views

urlpatterns = [
    url(r'^$', myapp_views.home, name='home'),
    url(r'^contact/$', myapp_views.contact, name='contact'),
    url(r'^login/$', auth_views.login, name='login'),
]

请注意,我们已经使用as myapp_viewsas auth_views,这允许我们views.py从多个应用程序导入,而不会发生冲突。

有关的更多信息,请参见Django URL调度程序文档urlpatterns

Django 1.10 no longer allows you to specify views as a string (e.g. 'myapp.views.home') in your URL patterns.

The solution is to update your urls.py to include the view callable. This means that you have to import the view in your urls.py. If your URL patterns don’t have names, then now is a good time to add one, because reversing with the dotted python path no longer works.

from django.conf.urls import include, url

from django.contrib.auth.views import login
from myapp.views import home, contact

urlpatterns = [
    url(r'^$', home, name='home'),
    url(r'^contact/$', contact, name='contact'),
    url(r'^login/$', login, name='login'),
]

If there are many views, then importing them individually can be inconvenient. An alternative is to import the views module from your app.

from django.conf.urls import include, url

from django.contrib.auth import views as auth_views
from myapp import views as myapp_views

urlpatterns = [
    url(r'^$', myapp_views.home, name='home'),
    url(r'^contact/$', myapp_views.contact, name='contact'),
    url(r'^login/$', auth_views.login, name='login'),
]

Note that we have used as myapp_views and as auth_views, which allows us to import the views.py from multiple apps without them clashing.

See the Django URL dispatcher docs for more information about urlpatterns.


回答 1

该错误仅意味着myapp.views.home不能调用它,就像函数一样。它实际上是一个字符串。当您的解决方案在django 1.9中运行时,它仍然发出警告,说它将从版本1.10开始弃用,这就是发生的一切。通过@Alasdair先前的溶液中导入必要的视图函数到脚本通过任一 from myapp import views as myapp_viewsfrom myapp.views import home, contact

This error just means that myapp.views.home is not something that can be called, like a function. It is a string in fact. While your solution works in django 1.9, nevertheless it throws a warning saying this will deprecate from version 1.10 onwards, which is exactly what has happened. The previous solution by @Alasdair imports the necessary view functions into the script through either from myapp import views as myapp_views or from myapp.views import home, contact


回答 2

如果视图和模块的名称冲突,也可能会出现此错误。我将我的视图文件分发到views文件夹下,/views/view1.py, /views/view2.py并在view2.py中导入了一个名为table.py的模型时遇到了错误,该模型恰巧是view1.py中的视图名称。因此,命名视图功能 v_table(request,id) 很有帮助。

You may also get this error if you have a name clash of a view and a module. I’ve got the error when i distribute my view files under views folder, /views/view1.py, /views/view2.py and imported some model named table.py in view2.py which happened to be a name of a view in view1.py. So naming the view functions as v_table(request,id) helped.


回答 3

您的代码是

urlpatterns = [
    url(r'^$', 'myapp.views.home'),
    url(r'^contact/$', 'myapp.views.contact'),
    url(r'^login/$', 'django.contrib.auth.views.login'),
]

在导入include()功能时将其更改为以下内容:

urlpatterns = [
    url(r'^$', views.home),
    url(r'^contact/$', views.contact),
    url(r'^login/$', views.login),
]

Your code is

urlpatterns = [
    url(r'^$', 'myapp.views.home'),
    url(r'^contact/$', 'myapp.views.contact'),
    url(r'^login/$', 'django.contrib.auth.views.login'),
]

change it to following as you’re importing include() function :

urlpatterns = [
    url(r'^$', views.home),
    url(r'^contact/$', views.contact),
    url(r'^login/$', views.login),
]

字典可以在创建时传递给Django模型吗?

问题:字典可以在创建时传递给Django模型吗?

是否有可能做类似这样的一个东西listdictionary还是其他什么东西?

data_dict = {
    'title' : 'awesome title',
    'body' : 'great body of text',
}

Model.objects.create(data_dict)

如果我可以扩展它,那就更好了:

Model.objects.create(data_dict, extra='hello', extra2='world')

Is it possible to do something similar to this with a list, dictionary or something else?

data_dict = {
    'title' : 'awesome title',
    'body' : 'great body of text',
}

Model.objects.create(data_dict)

Even better if I can extend it:

Model.objects.create(data_dict, extra='hello', extra2='world')

回答 0

如果titlebody是模型中的字段,则可以使用**运算符将关键字参数传递到字典中

假设您的模型称为MyModel

# create instance of model
m = MyModel(**data_dict)
# don't forget to save to database!
m.save()

至于第二个问题,字典必须是最后一个参数。同样,extra并且extra2应该是模型中的字段。

m2 =MyModel(extra='hello', extra2='world', **data_dict)
m2.save()

If title and body are fields in your model, then you can deliver the keyword arguments in your dictionary using the ** operator.

Assuming your model is called MyModel:

# create instance of model
m = MyModel(**data_dict)
# don't forget to save to database!
m.save()

As for your second question, the dictionary has to be the final argument. Again, extra and extra2 should be fields in the model.

m2 =MyModel(extra='hello', extra2='world', **data_dict)
m2.save()

回答 1

并不是直接回答问题,但是我发现这段代码帮助我创建了可以很好地保存为正确答案的字典。如果此数据将导出到json,则需要进行类型转换。

我希望这有帮助:

  #mod is a django database model instance
def toDict( mod ):
  import datetime
  from decimal import Decimal
  import re

    #Go through the object, load in the objects we want
  obj = {}
  for key in mod.__dict__:
    if re.search('^_', key):
      continue

      #Copy my data
    if isinstance( mod.__dict__[key], datetime.datetime ):
      obj[key] = int(calendar.timegm( ts.utctimetuple(mod.__dict__[key])))
    elif isinstance( mod.__dict__[key], Decimal ):
      obj[key] = float( mod.__dict__[key] )
    else:
      obj[key] = mod.__dict__[key]

  return obj 

def toCsv( mod, fields, delim=',' ):
  import datetime
  from decimal import Decimal

    #Dump the items
  raw = []
  for key in fields:
    if key not in mod.__dict__:
      continue

      #Copy my data
    if isinstance( mod.__dict__[key], datetime.datetime ):
      raw.append( str(calendar.timegm( ts.utctimetuple(mod.__dict__[key]))) )
    elif isinstance( mod.__dict__[key], Decimal ):
      raw.append( str(float( mod.__dict__[key] )))
    else:
      raw.append( str(mod.__dict__[key]) )

  return delim.join( raw )

Not directly an answer to the question, but I find this code helped me create the dicts that save nicely into the correct answer. The type conversions made are required if this data will be exported to json.

I hope this helps:

  #mod is a django database model instance
def toDict( mod ):
  import datetime
  from decimal import Decimal
  import re

    #Go through the object, load in the objects we want
  obj = {}
  for key in mod.__dict__:
    if re.search('^_', key):
      continue

      #Copy my data
    if isinstance( mod.__dict__[key], datetime.datetime ):
      obj[key] = int(calendar.timegm( ts.utctimetuple(mod.__dict__[key])))
    elif isinstance( mod.__dict__[key], Decimal ):
      obj[key] = float( mod.__dict__[key] )
    else:
      obj[key] = mod.__dict__[key]

  return obj 

def toCsv( mod, fields, delim=',' ):
  import datetime
  from decimal import Decimal

    #Dump the items
  raw = []
  for key in fields:
    if key not in mod.__dict__:
      continue

      #Copy my data
    if isinstance( mod.__dict__[key], datetime.datetime ):
      raw.append( str(calendar.timegm( ts.utctimetuple(mod.__dict__[key]))) )
    elif isinstance( mod.__dict__[key], Decimal ):
      raw.append( str(float( mod.__dict__[key] )))
    else:
      raw.append( str(mod.__dict__[key]) )

  return delim.join( raw )

如何禁用Django的CSRF验证?

问题:如何禁用Django的CSRF验证?

我已经在中注释掉了csrf处理器和中间件产品线settings.py

122 
123 TEMPLATE_CONTEXT_PROCESSORS = (
124     'django.contrib.auth.context_processors.auth',
125 #    'django.core.context_processors.csrf',
126     'django.core.context_processors.request',
127     'django.core.context_processors.static',
128     'cyathea.processors.static',
129 )
130 
131 MIDDLEWARE_CLASSES = (
132     'django.middleware.common.CommonMiddleware',
133     'django.contrib.sessions.middleware.SessionMiddleware',
134 #    'django.middleware.csrf.CsrfViewMiddleware',
135     'django.contrib.auth.middleware.AuthenticationMiddleware',
136     'django.contrib.messages.middleware.MessageMiddleware',
137     'django.middleware.locale.LocaleMiddleware',
138     # Uncomment the next line for simple clickjacking protection:
139     # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
140 )

但是,当我使用Ajax发送请求时,Django仍然会响应“ csrf令牌不正确或丢失”,并且在将X-CSRFToken添加到标头后,请求将会成功。

这里发生了什么 ?

I have commented out csrf processor and middleware lines in settings.py:

122 
123 TEMPLATE_CONTEXT_PROCESSORS = (
124     'django.contrib.auth.context_processors.auth',
125 #    'django.core.context_processors.csrf',
126     'django.core.context_processors.request',
127     'django.core.context_processors.static',
128     'cyathea.processors.static',
129 )
130 
131 MIDDLEWARE_CLASSES = (
132     'django.middleware.common.CommonMiddleware',
133     'django.contrib.sessions.middleware.SessionMiddleware',
134 #    'django.middleware.csrf.CsrfViewMiddleware',
135     'django.contrib.auth.middleware.AuthenticationMiddleware',
136     'django.contrib.messages.middleware.MessageMiddleware',
137     'django.middleware.locale.LocaleMiddleware',
138     # Uncomment the next line for simple clickjacking protection:
139     # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
140 )

But when I use Ajax to send a request, Django still respond ‘csrf token is incorrect or missing’, and after adding X-CSRFToken to headers, the request would succeed.

What is going on here ?


回答 0

如果只需要一些视图而不使用CSRF,则可以使用@csrf_exempt

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')

您可以在Django文档中找到更多示例和其他场景:

If you just need some views not to use CSRF, you can use @csrf_exempt:

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')

You can find more examples and other scenarios in the Django documentation:


回答 1

要为基于类的视图禁用CSRF,以下对我有用。
使用Django 1.10和python 3.5.2

from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

@method_decorator(csrf_exempt, name='dispatch')
class TestView(View):
    def post(self, request, *args, **kwargs):
        return HttpResponse('Hello world')

To disable CSRF for class based views the following worked for me.
Using django 1.10 and python 3.5.2

from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

@method_decorator(csrf_exempt, name='dispatch')
class TestView(View):
    def post(self, request, *args, **kwargs):
        return HttpResponse('Hello world')

回答 2

setting.pyMIDDLEWARE中,您可以简单地删除/注释此行:

'django.middleware.csrf.CsrfViewMiddleware',

In setting.py in MIDDLEWARE you can simply remove/comment this line:

'django.middleware.csrf.CsrfViewMiddleware',

回答 3

对于Django 2

from django.utils.deprecation import MiddlewareMixin


class DisableCSRF(MiddlewareMixin):
    def process_request(self, request):
        setattr(request, '_dont_enforce_csrf_checks', True)

必须settings.MIDDLEWARE在适当的时候(例如在您的测试设置中)添加该中间件。

注意:不再调用该设置MIDDLEWARE_CLASSES

For Django 2:

from django.utils.deprecation import MiddlewareMixin


class DisableCSRF(MiddlewareMixin):
    def process_request(self, request):
        setattr(request, '_dont_enforce_csrf_checks', True)

That middleware must be added to settings.MIDDLEWARE when appropriate (in your test settings for example).

Note: the setting isn’t not called MIDDLEWARE_CLASSES anymore.


回答 4

答案可能不合适,但希望对您有帮助

class DisableCSRFOnDebug(object):
    def process_request(self, request):
        if settings.DEBUG:
            setattr(request, '_dont_enforce_csrf_checks', True)

使用这样的中间件有助于调试请求并检查生产服务器中的csrf。

The answer might be inappropriate, but I hope it helps you

class DisableCSRFOnDebug(object):
    def process_request(self, request):
        if settings.DEBUG:
            setattr(request, '_dont_enforce_csrf_checks', True)

Having middleware like this helps to debug requests and to check csrf in production servers.


回答 5

这里的问题是SessionAuthentication执行自己的CSRF验证。这就是为什么即使在注释CSRF中间件的情况下也出现CSRF丢失错误的原因。您可以在每个视图中添加@csrf_exempt,但是如果您想禁用CSRF并为整个应用进行会话身份验证,则可以添加一个额外的中间件,如下所示:

class DisableCSRFMiddleware(object):

def __init__(self, get_response):
    self.get_response = get_response

def __call__(self, request):
    setattr(request, '_dont_enforce_csrf_checks', True)
    response = self.get_response(request)
    return response

我在myapp / middle.py中创建了该类,然后在Middleware的settings.py中导入了该中间件

MIDDLEWARE = [
    'django.middleware.common.CommonMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware',
    'myapp.middle.DisableCSRFMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',

]

可以在Django 1.11上使用DRF

The problem here is that SessionAuthentication performs its own CSRF validation. That is why you get the CSRF missing error even when the CSRF Middleware is commented. You could add @csrf_exempt to every view, but if you want to disable CSRF and have session authentication for the whole app, you can add an extra middleware like this –

class DisableCSRFMiddleware(object):

def __init__(self, get_response):
    self.get_response = get_response

def __call__(self, request):
    setattr(request, '_dont_enforce_csrf_checks', True)
    response = self.get_response(request)
    return response

I created this class in myapp/middle.py Then import this middleware in Middleware in settings.py

MIDDLEWARE = [
    'django.middleware.common.CommonMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware',
    'myapp.middle.DisableCSRFMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',

]

That works with DRF on django 1.11


回答 6

如果要在“全局”中禁用它,则可以编写自定义中间件,如下所示

from django.utils.deprecation import MiddlewareMixin

class DisableCsrfCheck(MiddlewareMixin):

    def process_request(self, req):
        attr = '_dont_enforce_csrf_checks'
        if not getattr(req, attr, False):
            setattr(req, attr, True)

然后将该类添加youappname.middlewarefilename.DisableCsrfCheckMIDDLEWARE_CLASSES列表中,然后django.middleware.csrf.CsrfViewMiddleware

If you want disable it in Global, you can write a custom middleware, like this

from django.utils.deprecation import MiddlewareMixin

class DisableCsrfCheck(MiddlewareMixin):

    def process_request(self, req):
        attr = '_dont_enforce_csrf_checks'
        if not getattr(req, attr, False):
            setattr(req, attr, True)

then add this class youappname.middlewarefilename.DisableCsrfCheck to MIDDLEWARE_CLASSES lists, before django.middleware.csrf.CsrfViewMiddleware


回答 7

CSRF可以在视图级别强制执行,不能全局禁用

在某些情况下,这很痛苦,但是,“这是为了安全”。保留这些AAA等级。

https://docs.djangoproject.com/en/dev/ref/csrf/#contrib-and-reusable-apps

CSRF can be enforced at the view level, which can’t be disabled globally.

In some cases this is a pain, but um, “it’s for security”. Gotta retain those AAA ratings.

https://docs.djangoproject.com/en/dev/ref/csrf/#contrib-and-reusable-apps


回答 8

@WoooHaaaa一些第三方程序包使用’django.middleware.csrf.CsrfViewMiddleware’中间件。例如,我使用django-rest-oauth,即使禁用了这些东西,我也遇到了类似您的问题。也许这些软件包像我的案例一样响应了您的请求,因为您使用了身份验证修饰符之类的东西。

@WoooHaaaa some third party packages use ‘django.middleware.csrf.CsrfViewMiddleware’ middleware. for example i use django-rest-oauth and i have problem like you even after disabling those things. maybe these packages responded to your request like my case, because you use authentication decorator and something like this.


排序查询集的好方法?-Django

问题:排序查询集的好方法?-Django

我想做的是这样的:

  • 获得得分最高的30位作者(Author.objects.order_by('-score')[:30]

  • 命令作者 last_name


有什么建议?

what I’m trying to do is this:

  • get the 30 Authors with highest score ( Author.objects.order_by('-score')[:30] )

  • order the authors by last_name


Any suggestions?


回答 0

关于什么

import operator

auths = Author.objects.order_by('-score')[:30]
ordered = sorted(auths, key=operator.attrgetter('last_name'))

在Django 1.4及更高版本中,您可以通过提供多个字段进行订购。
参考:https : //docs.djangoproject.com/en/dev/ref/models/querysets/#order-by

order_by(*字段)

默认情况下,a返回的结果由模型的Meta中QuerySetordering选项给出的排序元组排序。您可以使用order_by方法基于每个QuerySet重写此方法。

例:

ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]

上面的结果将按score降序排列,然后按last_name升序排列。前面的负号"-score"表示降序。隐含升序。

What about

import operator

auths = Author.objects.order_by('-score')[:30]
ordered = sorted(auths, key=operator.attrgetter('last_name'))

In Django 1.4 and newer you can order by providing multiple fields.
Reference: https://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by

order_by(*fields)

By default, results returned by a QuerySet are ordered by the ordering tuple given by the ordering option in the model’s Meta. You can override this on a per-QuerySet basis by using the order_by method.

Example:

ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]

The result above will be ordered by score descending, then by last_name ascending. The negative sign in front of "-score" indicates descending order. Ascending order is implied.


回答 1

我只是想说明一下内置解决方案(仅适用于SQL)并不总是最好的。最初,我认为因为Django的QuerySet.objects.order_by方法接受多个参数,所以您可以轻松地将它们链接起来:

ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]

但是,它没有按您期望的那样工作。举例来说,首先是按得分排序的总统列表(选择前5名以便于阅读):

>>> auths = Author.objects.order_by('-score')[:5]
>>> for x in auths: print x
... 
James Monroe (487)
Ulysses Simpson (474)
Harry Truman (471)
Benjamin Harrison (467)
Gerald Rudolph (464)

使用Alex Martelli的解决方案,该解决方案可准确提供排名前5位的人员last_name

>>> for x in sorted(auths, key=operator.attrgetter('last_name')): print x
... 
Benjamin Harrison (467)
James Monroe (487)
Gerald Rudolph (464)
Ulysses Simpson (474)
Harry Truman (471)

现在组合order_by调用:

>>> myauths = Author.objects.order_by('-score', 'last_name')[:5]
>>> for x in myauths: print x
... 
James Monroe (487)
Ulysses Simpson (474)
Harry Truman (471)
Benjamin Harrison (467)
Gerald Rudolph (464)

如您所见,它与第一个结果相同,这意味着它无法按预期工作。

I just wanted to illustrate that the built-in solutions (SQL-only) are not always the best ones. At first I thought that because Django’s QuerySet.objects.order_by method accepts multiple arguments, you could easily chain them:

ordered_authors = Author.objects.order_by('-score', 'last_name')[:30]

But, it does not work as you would expect. Case in point, first is a list of presidents sorted by score (selecting top 5 for easier reading):

>>> auths = Author.objects.order_by('-score')[:5]
>>> for x in auths: print x
... 
James Monroe (487)
Ulysses Simpson (474)
Harry Truman (471)
Benjamin Harrison (467)
Gerald Rudolph (464)

Using Alex Martelli’s solution which accurately provides the top 5 people sorted by last_name:

>>> for x in sorted(auths, key=operator.attrgetter('last_name')): print x
... 
Benjamin Harrison (467)
James Monroe (487)
Gerald Rudolph (464)
Ulysses Simpson (474)
Harry Truman (471)

And now the combined order_by call:

>>> myauths = Author.objects.order_by('-score', 'last_name')[:5]
>>> for x in myauths: print x
... 
James Monroe (487)
Ulysses Simpson (474)
Harry Truman (471)
Benjamin Harrison (467)
Gerald Rudolph (464)

As you can see it is the same result as the first one, meaning it doesn’t work as you would expect.


回答 2

这是一种允许得分临界值的方法。

author_count = Author.objects.count()
cut_off_score = Author.objects.order_by('-score').values_list('score')[min(30, author_count)]
top_authors = Author.objects.filter(score__gte=cut_off_score).order_by('last_name')

这样一来,您在top_authors中可能会获得30多位作者,如果您的作者少于30位,则可以在此处找到min(30,author_count)

Here’s a way that allows for ties for the cut-off score.

author_count = Author.objects.count()
cut_off_score = Author.objects.order_by('-score').values_list('score')[min(30, author_count)]
top_authors = Author.objects.filter(score__gte=cut_off_score).order_by('last_name')

You may get more than 30 authors in top_authors this way and the min(30,author_count) is there incase you have fewer than 30 authors.


如何在Django中重置数据库?我收到命令“重置”未找到错误

问题:如何在Django中重置数据库?我收到命令“重置”未找到错误

在此处按照示例通过Django进行学习:http://lightbird.net/dbe/todo_list.html

该教程说:

“这改变了我们的表布局,我们必须要求Django重置并重新创建表:

manage.py reset todo; manage.py syncdb

但是,当我运行时manage.py reset todo,出现错误:

$ python manage.py reset todo                                       
- Unknown command: 'reset'

这是因为我使用的是sqlite3而不是Postgresql吗?

有人可以告诉我重置数据库的命令是什么吗?

命令:python manage.py sqlclear todo返回错误:

$ python manage.py sqlclear todo    
CommandError: App with label todo could not be found.    
Are you sure your INSTALLED_APPS setting is correct?

因此,我在settings.py的INSTALLED_APPS中添加了“ todo”,然后python manage.py sqlclear todo再次运行,导致此错误:

$ python manage.py sqlclear todo                                      
- NameError: name 'admin' is not defined

Following this Django by Example tutotrial here: http://lightbird.net/dbe/todo_list.html

The tutorial says:

“This changes our table layout and we’ll have to ask Django to reset and recreate tables:

manage.py reset todo; manage.py syncdb

though, when I run manage.py reset todo, I get the error:

$ python manage.py reset todo                                       
- Unknown command: 'reset'

Is this because I am using sqlite3 and not postgresql?

Can somebody tell me what the command is to reset the database?

The command: python manage.py sqlclear todo returns the error:

$ python manage.py sqlclear todo    
CommandError: App with label todo could not be found.    
Are you sure your INSTALLED_APPS setting is correct?

So I added ‘todo’ to my INSTALLED_APPS in settings.py, and ran python manage.py sqlclear todo again, resulting in this error:

$ python manage.py sqlclear todo                                      
- NameError: name 'admin' is not defined

回答 0

reset已被flushDjango 1.5 取代,请参阅:

python manage.py help flush

reset has been replaced by flush with Django 1.5, see:

python manage.py help flush

回答 1

看起来“冲洗”答案适用于部分情况,但不是全部情况。我不仅需要刷新数据库中的值,还需要正确地重新创建表。我还没有使用迁移(早期),所以我确实需要删除所有表。

我发现删除所有表的两种方法都需要核心django以外的东西。

如果您使用的是Heroku,请使用pg:reset删除所有表:

heroku pg:reset DATABASE_URL
heroku run python manage.py syncdb

如果您可以安装Django扩展,则可以通过以下方式完全重置:

python ./manage.py reset_db --router=default

It looks like the ‘flush’ answer will work for some, but not all cases. I needed not just to flush the values in the database, but to recreate the tables properly. I’m not using migrations yet (early days) so I really needed to drop all the tables.

Two ways I’ve found to drop all tables, both require something other than core django.

If you’re on Heroku, drop all the tables with pg:reset:

heroku pg:reset DATABASE_URL
heroku run python manage.py syncdb

If you can install Django Extensions, it has a way to do a complete reset:

python ./manage.py reset_db --router=default

回答 2

与LisaD的答案类似,Django扩展具有出色的reset_db命令,该命令可以完全删除所有内容,而不仅仅是像“ flush”一样截断表。

python ./manage.py reset_db

仅仅刷新表并不能解决在删除对象时发生的永久性错误。进行reset_db解决了该问题。

Similar to LisaD’s answer, Django Extensions has a great reset_db command that totally drops everything, instead of just truncating the tables like “flush” does.

python ./manage.py reset_db

Merely flushing the tables wasn’t fixing a persistent error that occurred when I was deleting objects. Doing a reset_db fixed the problem.


回答 3

如果您使用的是Django 2.0,那么

python manage.py flush 

将工作

if you are using Django 2.0 Then

python manage.py flush 

will work


回答 4

如果要清理整个数据库,则可以使用: python manage.py flush 如果要清理Django应用程序的数据库表,则可以使用: python manage.py migration appname 0

If you want to clean the whole database, you can use: python manage.py flush If you want to clean database table of a Django app, you can use: python manage.py migrate appname zero


回答 5

使用django 1.11,只需从migrations每个应用程序的文件夹中删除所有迁移文件(除外的所有文件__init__.py)。然后

  1. 手动删除数据库。
  2. 手动创建数据库。
  3. 运行python3 manage.py makemigrations
  4. 运行python3 manage.py migrate

瞧,您的数据库已完全重置。

With django 1.11, simply delete all migration files from the migrations folder of each application (all files except __init__.py). Then

  1. Manually drop database.
  2. Manually create database.
  3. Run python3 manage.py makemigrations.
  4. Run python3 manage.py migrate.

And voilla, your database has been completely reset.


回答 6

对我来说,这解决了问题。

heroku pg:reset DATABASE_URL

heroku run bash
>> Inside heroku bash
cd app_name && rm -rf migrations && cd ..
./manage.py makemigrations app_name
./manage.py migrate

For me this solved the problem.

heroku pg:reset DATABASE_URL

heroku run bash
>> Inside heroku bash
cd app_name && rm -rf migrations && cd ..
./manage.py makemigrations app_name
./manage.py migrate

回答 7

只是跟进@LisaD的答案。
截至2016年(Django 1.9),您需要输入:

heroku pg:reset DATABASE_URL
heroku run python manage.py makemigrations
heroku run python manage.py migrate

这将为您提供Heroku中的全新数据库。

Just a follow up to @LisaD’s answer.
As of 2016 (Django 1.9), you need to type:

heroku pg:reset DATABASE_URL
heroku run python manage.py makemigrations
heroku run python manage.py migrate

This will give you a fresh new database within Heroku.


回答 8

  1. 只需手动删除数据库即可。确保首先创建备份(在我的情况下db.sqlite3是我的数据库)

  2. 运行此命令 manage.py migrate

  1. Just manually delete you database. Ensure you create backup first (in my case db.sqlite3 is my database)

  2. Run this command manage.py migrate


回答 9

python manage.py flush

删除旧的数据库内容,

不要忘记创建新的超级用户:

python manage.py createsuperuser
python manage.py flush

deleted old db contents,

Don’t forget to create new superuser:

python manage.py createsuperuser