Repository: pydantic/pydantic

Issue:
BaseModel.construct(): Incorrect field order with default values
### Checks

* [x] I added a descriptive title to this issue
* [x] I have searched (google, github) for similar issues and couldn't find anything
* [x] I have read and followed [the docs](https://pydantic-docs.helpmanual.io/) and still think this is a bug

<!-- Sorry to sound so draconian, but every second saved replying to issues is time spend improving pydantic :-) -->

# Bug

Output of `python -c "import pydantic.utils; print(pydantic.utils.version_info())"`:
```
             pydantic version: 1.7.3
            pydantic compiled: True
                 install path: C:\Users\JonasTK\miniconda3\envs\testenv\Lib\site-packages\pydantic
               python version: 3.8.5 (default, Sep  3 2020, 21:29:08) [MSC v.1916 64 bit (AMD64)]
                     platform: Windows-10-10.0.19041-SP0
     optional deps. installed: ['typing-extensions']
```
<!-- or if you're using pydantic prior to v1.3, manually include: OS, python version and pydantic version -->

<!-- Please read the [docs](https://pydantic-docs.helpmanual.io/) and search through issues to
confirm your bug hasn't already been reported. -->

<!-- Where possible please include a self-contained code snippet describing your bug: -->

I know this is (sort of) showcased in the docs, but I still think it is a problem that .construct() does not give correct field order when there are fields with default values. Most of the time this is not a problem: comparing instances and .dict() outputs do not depend on the field order. But for JSON export, it does matter.

Shouldn't the JSON export from an instance generated via .construct() with pre-validated input be identical to the JSON export of a properly validated instance?

```py
from pydantic import BaseModel


class Foo(BaseModel):
    a: int
    b: int = 42
    c: float


instance = Foo(a=1, c=3.14)  # Correct field order
instance_construct = Foo.construct(**instance.dict())  # Incorrect field order

print(instance)            # Output: a=1 b=42 c=3.14
print(instance_construct)  # Output: b=42 a=1 c=3.14

print(instance.json())            # Output: {"a": 1, "b": 42, "c": 3.14}
print(instance_construct.json())  # Output: {"b": 42, "a": 1, "c": 3.14}

assert instance == instance_construct  # No Error
assert instance.dict() == instance_construct.dict()  # No Error
assert instance.json() == instance_construct.json()  # AssertionError
```



Discussion:

Resolving patch:
diff --git a/pydantic/main.py b/pydantic/main.py
--- a/pydantic/main.py
+++ b/pydantic/main.py
@@ -584,10 +584,15 @@ def construct(cls: Type['Model'], _fields_set: Optional['SetStr'] = None, **valu
         """
         Creates a new model setting __dict__ and __fields_set__ from trusted or pre-validated data.
         Default values are respected, but no other validation is performed.
+        Behaves as if `Config.extra = 'allow'` was set since it adds all passed values
         """
         m = cls.__new__(cls)
-        # default field values
-        fields_values = {name: field.get_default() for name, field in cls.__fields__.items() if not field.required}
+        fields_values: Dict[str, Any] = {}
+        for name, field in cls.__fields__.items():
+            if name in values:
+                fields_values[name] = values[name]
+            elif not field.required:
+                fields_values[name] = field.get_default()
         fields_values.update(values)
         object_setattr(m, '__dict__', fields_values)
         if _fields_set is None:


Test patch:
diff --git a/tests/test_construction.py b/tests/test_construction.py
--- a/tests/test_construction.py
+++ b/tests/test_construction.py
@@ -35,6 +35,28 @@ def test_construct_fields_set():
     assert m.dict() == {'a': 3, 'b': -1}
 
 
+def test_construct_allow_extra():
+    """construct() should allow extra fields"""
+
+    class Foo(BaseModel):
+        x: int
+
+    assert Foo.construct(x=1, y=2).dict() == {'x': 1, 'y': 2}
+
+
+def test_construct_keep_order():
+    class Foo(BaseModel):
+        a: int
+        b: int = 42
+        c: float
+
+    instance = Foo(a=1, b=321, c=3.14)
+    instance_construct = Foo.construct(**instance.dict())
+    assert instance == instance_construct
+    assert instance.dict() == instance_construct.dict()
+    assert instance.json() == instance_construct.json()
+
+
 def test_large_any_str():
     class Model(BaseModel):
         a: bytes