webentwicklung-frage-antwort-db.com.de

Wie legst du einen Standard für ein Django ForeignKey Model- oder AdminModel-Feld fest?

Wie kann ich einen Standardwert für ein ForeignKey-Feld in einem Django Model oder AdminModel festlegen?

So ähnlich (aber das funktioniert natürlich nicht) ...

created_by = models.ForeignKey(User, default=request.user)

Ich weiß, dass ich es in der Ansicht "austricksen" kann, aber in Bezug auf das AdminModel scheint es nicht möglich zu sein.

20
T. Stone
class Foo(models.Model):
    a = models.CharField(max_length=42)

class Bar(models.Model):
    b = models.CharField(max_length=42)
    a = models.ForeignKey(Foo, default=lambda: Foo.objects.get(id=1) )
30

Hier ist eine Lösung, die in Django 1.7 funktioniert. Anstatt den Standardwert bei der Felddefinition anzugeben, setzen Sie ihn auf null, überschreiben Sie jedoch die Funktion 'save', um ihn beim ersten Mal zu füllen (solange er null ist):

class Foo(models.Model):
    a = models.CharField(max_length=42)

class Bar(models.Model):
    b = models.CharField(max_length=42)
    a = models.ForeignKey(Foo, null=True)

    def save(self, *args, **kwargs):
        if self.a is None:  # Set default reference
            self.a = Foo.objects.get(id=1)
        super(Bar, self).save(*args, **kwargs)
10
o_c

Für Django 1.7 oder höher

Erstellen Sie einfach ein ForeignKey-Objekt und speichern Sie es. Der Standardwert kann die ID des Objekts sein, das standardmäßig verknüpft werden soll.

Zum Beispiel,

created_by = models.ForeignKey(User, default=1)

Wenn Sie die Entwicklungsversion von Django verwenden, können Sie die formfield_for_foreignkey() -Methode in Ihrer AdminModel implementieren, um einen Standardwert festzulegen.

5
Steef

Ich habe das ähnlich wie @o_c gemacht, aber ich würde lieber get_or_create als nur eine einfache pk verwenden.

class UserSettings(models.Model):
    name = models.CharField(max_length=64, unique=True)
    # ... some other fields 

    @staticmethod
    def get_default_user_settings():
        user_settings, created = UserSettings.objects.get_or_create(
            name = 'Default settings'
        )
        return user_settings

class SiteUser(...):
    # ... some other fields

    user_settings = models.ForeignKey(
        to=UserSettings, 
        on_delete=models.SET_NULL, 
        null=True
    )

    def save(self, *args, **kwargs):
        if self.user_settings is None:
            self.user_settings = UserSettings.get_default_params()
        super(SiteUser, self).save(*args, **kwargs)
3
Max Malysh
def get_user_default_id():
    return 1

created_by = models.ForeignKey(User, default=get_user_default_id)
1
Philippos

Was mich betrifft, für Django 1.7 ist es nur pk:

category = models.ForeignKey(Category, editable=False, default=1)

aber denken Sie daran, dass die Migration so aussieht

migrations.AlterField(
            model_name='item',
            name='category',
            field=models.ForeignKey(default=1, editable=False, to='item.Category'),
            preserve_default=True,
        ),

ich glaube nicht, dass es mit dem dynamischen Benutzer pk zu arbeiten ist.

1
LennyLip

Für Django> = 1.7 können Sie den Standardwert für ein ForeignKey-Feld auf zwei verschiedene Arten festlegen:

1) Direkt als ganze Zahl

DEFAULT_CREATED_BY_USER = 42

class MyModel(Model):
    created_by = models.ForeignKey(User, default=DEFAULT_CREATED_BY_USER)

2) Als Nicht-Lambda-Callable, das eine ganze Zahl zurückgibt

Sie können auch eine aufrufbare Datei verwenden, die in einen vollständigen Modulpfad aufgelöst werden kann. Dies bedeutet, dass Lambdas nicht funktionieren. Aber das wird:

def default_created_by_user():
    return 42

class MyModel(Model):
    created_by = models.ForeignKey(User, default=default_created_by_user)

Verweise:

1
Rune Kaagaard

Dies ist eine geringfügige Änderung der Antwort von o_c . Es sollte Ihnen einen Treffer in der Datenbank ersparen. Beachten Sie, dass ich in der Speichermethode self.a_id = 1 anstelle von self.a = Foo.objects.get (id = 1) verwende. Es hat den gleichen Effekt, ohne Foo abfragen zu müssen.

class Foo(models.Model):
    a = models.CharField(max_length=42)

class Bar(models.Model):
    b = models.CharField(max_length=42)
    a = models.ForeignKey(Foo, null=True)

    def save(self, *args, **kwargs):
        if self.a is None:  # Set default reference
            self.a_id = 1
        super(Bar, self).save(*args, **kwargs)
1
Andrew Simpson

Verwenden Sie anstelle der Lambda-Funktion die Teilfunktion. Die Lambda-Funktion ist keine Serialisierung und führt daher zu Migrationsfehlern.

class Foo(models.Model):
    a = models.CharField(max_length=42)

class Bar(models.Model):
    b = models.CharField(max_length=42)
    a = models.ForeignKey(Foo, default=partial(Foo.objects.get, id=1 ))
0
Kedar Jathar

Sie sollten Einstellungen bezüglich setting.AUTH_USER_MODEL in der settings.py-Datei haben.

Sie können im folgenden Dokument nachschauen:

" https://docs.djangoproject.com/de/1.10/topics/auth/customizing/#substituting-a-custom-user-model "

0
vikasvmads

Aus all den Iterationen heraus, um eine bessere Lösung zu finden, wird das Erstellen einer kleinen Funktion die Komplexität der Aufgabe erheblich lösen. Da einige der Lösungen in neueren Django Versionen veraltet sind oder länger unterstützt werden.

def get_request_user():
    # or any complex query result to set default value in ForeignKey
    return request.user.id

Dann können Sie die obige Funktion als Argument in ForeignKey übergeben.

created_by = models.ForeignKey(User, default=get_request_user)
0
nishit chittora

Sie können die Methode get_form Ihres Modelladministrators überschreiben.

admin.py

class YourModelAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        form = super(YourModelAdmin, self).get_form(request, obj, **kwargs)
        form.base_fields['created_by'].initial = request.user
    return form

admin.site.register(YourModel, YourModelAdmin)
0
Anusha Prasanth